From 551da078525246abc0aa7e1444137dc4d43b7b23 Mon Sep 17 00:00:00 2001 From: Jacek Date: Wed, 15 Sep 2021 14:44:35 +0200 Subject: [PATCH] SONAR-15202 Fix display of sub-portfolio as favorite --- .../sonar/server/ui/ws/ComponentAction.java | 13 ++-- .../server/ui/ws/ComponentActionTest.java | 70 ++++++++++++++++--- .../resources/org/sonar/l10n/core.properties | 4 +- 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java index c52ec34432a..2a04a40ae05 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java @@ -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 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 qualityProfiles = dbClient.liveMeasureDao().selectMeasure(dbSession, component.projectUuid(), QUALITY_PROFILES_KEY) .map(LiveMeasureDto::getDataAsString) diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java index 7e2cb216de2..0dc807153d1 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java @@ -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) { diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 4fa48c8c02d..2af634fa6ae 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -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. -- 2.39.5