]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15202 Fix display of sub-portfolio as favorite
authorJacek <jacek.poreda@sonarsource.com>
Wed, 15 Sep 2021 12:44:35 +0000 (14:44 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 16 Sep 2021 20:03:30 +0000 (20:03 +0000)
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index c52ec34432a6d1643aecb5acfd53b971e3547ed0..2a04a40ae0503817718832562ebd2125db89e14e 100644 (file)
@@ -33,6 +33,7 @@ import org.sonar.api.config.Configuration;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypes;
+import org.sonar.api.resources.Scopes;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -100,7 +101,7 @@ public class ComponentAction implements NavigationWsAction {
   private final Configuration config;
 
   public ComponentAction(DbClient dbClient, PageRepository pageRepository, ResourceTypes resourceTypes, UserSession userSession,
-                         ComponentFinder componentFinder, QualityGateFinder qualityGateFinder, Configuration config) {
+    ComponentFinder componentFinder, QualityGateFinder qualityGateFinder, Configuration config) {
     this.dbClient = dbClient;
     this.pageRepository = pageRepository;
     this.resourceTypes = resourceTypes;
@@ -160,7 +161,7 @@ public class ComponentAction implements NavigationWsAction {
 
       try (JsonWriter json = response.newJsonWriter()) {
         json.beginObject();
-        boolean isFavourite = isFavourite(session, rootProject);
+        boolean isFavourite = isFavourite(session, rootProject, component);
         writeComponent(json, component, analysis.orElse(null), isFavourite);
         writeProfiles(json, session, component);
         writeQualityGate(json, session, rootProject);
@@ -224,16 +225,20 @@ public class ComponentAction implements NavigationWsAction {
     }
   }
 
-  private boolean isFavourite(DbSession session, ComponentDto component) {
+  private boolean isFavourite(DbSession session, ComponentDto rootComponent, ComponentDto component) {
     PropertyQuery propertyQuery = PropertyQuery.builder()
       .setUserUuid(userSession.getUuid())
       .setKey("favourite")
-      .setComponentUuid(component.uuid())
+      .setComponentUuid(isSubview(component) ? component.uuid() : rootComponent.uuid())
       .build();
     List<PropertyDto> componentFavourites = dbClient.propertiesDao().selectByQuery(propertyQuery, session);
     return componentFavourites.size() == 1;
   }
 
+  private static boolean isSubview(ComponentDto component) {
+    return Qualifiers.SUBVIEW.equals(component.qualifier()) && Scopes.PROJECT.equals(component.scope());
+  }
+
   private void writeProfiles(JsonWriter json, DbSession dbSession, ComponentDto component) {
     Set<QualityProfile> qualityProfiles = dbClient.liveMeasureDao().selectMeasure(dbSession, component.projectUuid(), QUALITY_PROFILES_KEY)
       .map(LiveMeasureDto::getDataAsString)
index 7e2cb216de2cfc13932a877dcdf9f93f642d455f..0dc807153d1524175e11f7c9c71f6730cb303d28 100644 (file)
@@ -85,6 +85,7 @@ import static org.sonar.db.component.ComponentTesting.newDirectory;
 import static org.sonar.db.component.ComponentTesting.newFileDto;
 import static org.sonar.db.component.ComponentTesting.newModuleDto;
 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
+import static org.sonar.db.component.ComponentTesting.newSubPortfolio;
 import static org.sonar.db.component.SnapshotTesting.newAnalysis;
 import static org.sonar.db.measure.MeasureTesting.newLiveMeasure;
 import static org.sonar.db.metric.MetricTesting.newMetricDto;
@@ -189,6 +190,60 @@ public class ComponentActionTest {
       "}\n");
   }
 
+  @Test
+  public void return_favourite_for_subportfolio() {
+    db.qualityGates().createDefaultQualityGate();
+    ComponentDto portfolio = componentDbTester.insertPrivatePortfolio();
+    ComponentDto subportfolio = componentDbTester.insertComponent(newSubPortfolio(portfolio));
+    UserDto user = db.users().insertUser("obiwan");
+
+    // set favourite for sub portfolio
+    propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setComponentUuid(subportfolio.uuid()).setUserUuid(user.getUuid()),
+      subportfolio.getKey(), subportfolio.name(), subportfolio.qualifier(), user.getLogin());
+
+    userSession.logIn(user).addProjectPermission(UserRole.USER, subportfolio);
+    init();
+
+    String json = ws.newRequest()
+      .setParam("component", subportfolio.getKey())
+      .execute()
+      .getInput();
+
+    assertJson(json).isSimilarTo("{" +
+      "  \"key\": \"" + subportfolio.getDbKey() + "\"," +
+      "  \"isFavorite\": true," +
+      "  \"id\": \"" + subportfolio.uuid() + "\"," +
+      "  \"name\": \"" + subportfolio.name() + "\"" +
+      "}");
+  }
+
+  @Test
+  public void return_favourite_for_portfolio() {
+    db.qualityGates().createDefaultQualityGate();
+    ComponentDto portfolio = componentDbTester.insertPrivatePortfolio();
+    ComponentDto subportfolio = componentDbTester.insertComponent(newSubPortfolio(portfolio));
+    UserDto user = db.users().insertUser("obiwan");
+
+    // set favourite for sub portfolio
+    propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setComponentUuid(portfolio.uuid()).setUserUuid(user.getUuid()),
+      subportfolio.getKey(), portfolio.name(), portfolio.qualifier(), user.getLogin());
+
+    userSession.logIn(user).addProjectPermission(UserRole.USER, portfolio);
+    init();
+
+    String json = ws.newRequest()
+      .setParam("component", portfolio.getKey())
+      .execute()
+      .getInput();
+
+    assertJson(json).isSimilarTo("{" +
+      "  \"key\": \"" + portfolio.getDbKey() + "\"," +
+      "  \"isFavorite\": true," +
+      "  \"id\": \"" + portfolio.uuid() + "\"," +
+      "  \"name\": \"" + portfolio.name() + "\"" +
+      "}");
+  }
+
   @Test
   public void return_component_info_when_snapshot() {
     ComponentDto project = insertProject();
@@ -683,12 +738,11 @@ public class ComponentActionTest {
 
   private ComponentDto insertProject() {
     db.qualityGates().createDefaultQualityGate();
-    return db.components().insertPrivateProject("abcd", p ->
-      p.setDbKey("polop")
-        .setName("Polop")
-        .setDescription("test project")
-        .setQualifier(Qualifiers.PROJECT)
-        .setScope(Scopes.PROJECT));
+    return db.components().insertPrivateProject("abcd", p -> p.setDbKey("polop")
+      .setName("Polop")
+      .setDescription("test project")
+      .setQualifier(Qualifiers.PROJECT)
+      .setScope(Scopes.PROJECT));
   }
 
   private void init(Page... pages) {
@@ -697,7 +751,7 @@ public class ComponentActionTest {
     when(pluginRepository.getPluginInfo(any())).thenReturn(new PluginInfo("unused").setVersion(Version.create("1.0")));
     CoreExtensionRepository coreExtensionRepository = mock(CoreExtensionRepository.class);
     when(coreExtensionRepository.isInstalled(any())).thenReturn(false);
-    PageRepository pageRepository = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[]{context -> {
+    PageRepository pageRepository = new PageRepository(pluginRepository, coreExtensionRepository, new PageDefinition[] {context -> {
       for (Page page : pages) {
         context.addPage(page);
       }
@@ -747,7 +801,7 @@ public class ComponentActionTest {
       .setAdmin(true)
       .build();
 
-    return new Page[]{page1, page2, adminPage};
+    return new Page[] {page1, page2, adminPage};
   }
 
   private void verifySuccess(String componentKey) {
index 4fa48c8c02d42406403f1fdd9d8b9adf8b5f0640..2af634fa6ae806115567150ba4cb6939593172ee 100644 (file)
@@ -4148,14 +4148,14 @@ favorite.action.add=Add project to favorites
 favorite.action.remove=Remove project from favorites
 favorite.check.TRK=Click to mark this project as favorite.
 favorite.check.VW=Click to mark this portfolio as favorite.
-favorite.check.SVW=Click to mark this sub-ortfolio as favorite.
+favorite.check.SVW=Click to mark this sub-portfolio as favorite.
 favorite.check.APP=Click to mark this application as favorite.
 favorite.check.FIL=Click to mark this file as favorite.
 favorite.check.UTS=Click to mark this test file as favorite.
 
 favorite.current.TRK=This project is marked as favorite.
 favorite.current.VW=This portfolio is marked as favorite.
-favorite.current.SVW=This sub-ortfolio is marked as favorite.
+favorite.current.SVW=This sub-portfolio is marked as favorite.
 favorite.current.APP=This application is marked as favorite.
 favorite.current.FIL=This file is marked as favorite.
 favorite.current.UTS=This test file is marked as favorite.