From 58e9f8b9ad49d518712ad14fa33fd51e232a7cd6 Mon Sep 17 00:00:00 2001 From: Guillaume Jambet Date: Wed, 21 Feb 2018 15:13:35 +0100 Subject: [PATCH] SONAR-10426 Allow homepage on PORTFOLIOS, PORTFOLIO and on APPLICATION in SonarQube --- .../sonar/server/user/ws/CurrentAction.java | 16 ++++- .../sonar/server/user/ws/HomepageTypes.java | 2 +- .../server/user/ws/SetHomepageAction.java | 16 +++-- .../server/user/ws/CurrentActionTest.java | 38 ++++++++++++ .../server/user/ws/SetHomepageActionTest.java | 58 ++++++++++++++++++- sonar-ws/src/main/protobuf/ws-users.proto | 3 + 6 files changed, 122 insertions(+), 11 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java index cb959d11605..3b7ad430f56 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java @@ -46,7 +46,9 @@ import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.Users.CurrentWsResponse.Permissions; import static org.sonarqube.ws.Users.CurrentWsResponse.newBuilder; +import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.APPLICATION; import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.ORGANIZATION; +import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PORTFOLIO; import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PROJECT; import static org.sonarqube.ws.client.user.UsersWsParameters.ACTION_CURRENT; @@ -57,6 +59,7 @@ public class CurrentAction implements UsersWsAction { private final DefaultOrganizationProvider defaultOrganizationProvider; private final AvatarResolver avatarResolver; private final HomepageTypes homepageTypes; + private static final String HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL = "Homepage parameter should not be null"; public CurrentAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, AvatarResolver avatarResolver, HomepageTypes homepageTypes) { @@ -138,7 +141,7 @@ public class CurrentAction implements UsersWsAction { private void setHomepageParameter(DbSession dbSession, String homepageType, @Nullable String homepageParameter, CurrentWsResponse.Homepage.Builder homepage) { if (PROJECT.toString().equals(homepageType)) { - checkState(homepageParameter != null, "Homepage parameter should not be null"); + checkState(homepageParameter != null, HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL); ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, homepageParameter) .or(() -> { throw new IllegalStateException(format("Unknown component '%s' for homepageParameter", homepageParameter)); @@ -147,8 +150,17 @@ public class CurrentAction implements UsersWsAction { setNullable(component.getBranch(), homepage::setBranch); return; } + if (APPLICATION.toString().equals(homepageType) || PORTFOLIO.toString().equals(homepageType)) { + checkState(homepageParameter != null, HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL); + ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, homepageParameter) + .or(() -> { + throw new IllegalStateException(format("Unknown component '%s' for homepageParameter", homepageParameter)); + }); + homepage.setComponent(component.getKey()); + return; + } if (ORGANIZATION.toString().equals(homepageType)) { - checkState(homepageParameter != null, "Homepage parameter should not be null"); + checkState(homepageParameter != null, HOMEPAGE_PARAMETER_SHOULD_NOT_BE_NULL); OrganizationDto organization = dbClient.organizationDao().selectByUuid(dbSession, homepageParameter) .orElseThrow(() -> new IllegalStateException(format("Unknown organization '%s' for homepageParameter", homepageParameter))); homepage.setOrganization(organization.getKey()); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java index 2e00e41444e..be7f40ebc60 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java @@ -28,7 +28,7 @@ public interface HomepageTypes { /** * These types in only available on SonarQube */ - PROJECTS, ISSUES, + PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION, /** * These types are only available on SonarCloud */ diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java index 3047f3b5be7..d9fb7b1fd8e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java @@ -47,9 +47,10 @@ public class SetHomepageAction implements UsersWsAction { private static final String ACTION = "set_homepage"; public static final String PARAM_TYPE = "type"; - private static final String PARAM_ORGANIZATION = "organization"; - private static final String PARAM_COMPONENT = "component"; - private static final String PARAM_BRANCH = "branch"; + public static final String PARAM_ORGANIZATION = "organization"; + public static final String PARAM_COMPONENT = "component"; + public static final String PARAM_BRANCH = "branch"; + private static final String PARAMETER_REQUIRED = "Type %s requires a parameter '%s'"; private final UserSession userSession; private final DbClient dbClient; @@ -120,13 +121,18 @@ public class SetHomepageAction implements UsersWsAction { @Nullable String organizationParameter) { switch (type) { case PROJECT: - checkArgument(isNotBlank(componentParameter), "Type %s requires a parameter '%s'", type.name(), PARAM_COMPONENT); + checkArgument(isNotBlank(componentParameter), PARAMETER_REQUIRED, type.name(), PARAM_COMPONENT); return componentFinder.getByKeyAndOptionalBranch(dbSession, componentParameter, branchParameter).uuid(); + case PORTFOLIO: + case APPLICATION: + checkArgument(isNotBlank(componentParameter), PARAMETER_REQUIRED, type.name(), PARAM_COMPONENT); + return componentFinder.getByKey(dbSession, componentParameter).uuid(); case ORGANIZATION: - checkArgument(isNotBlank(organizationParameter), "Type %s requires a parameter '%s'", type.name(), PARAM_ORGANIZATION); + checkArgument(isNotBlank(organizationParameter), PARAMETER_REQUIRED, type.name(), PARAM_ORGANIZATION); return dbClient.organizationDao().selectByKey(dbSession, organizationParameter) .orElseThrow(() -> new NotFoundException(format("No organizationDto with key '%s'", organizationParameter))) .getUuid(); + case PORTFOLIOS: case PROJECTS: case ISSUES: case MY_PROJECTS: diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java index 9f83fce0273..7748ff91811 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java @@ -166,6 +166,44 @@ public class CurrentActionTest { .containsExactly(CurrentWsResponse.HomepageType.MY_PROJECTS); } + @Test + public void return_homepage_when_set_to_portfolios() { + UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIOS")); + userSessionRule.logIn(user); + + CurrentWsResponse response = call(); + + assertThat(response.getHomepage()) + .extracting(CurrentWsResponse.Homepage::getType) + .containsExactly(CurrentWsResponse.HomepageType.PORTFOLIOS); + } + + @Test + public void return_homepage_when_set_to_a_portfolio() { + ComponentDto portfolio = db.components().insertPrivatePortfolio(db.getDefaultOrganization()); + UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIO").setHomepageParameter(portfolio.uuid())); + userSessionRule.logIn(user); + + CurrentWsResponse response = call(); + + assertThat(response.getHomepage()) + .extracting(CurrentWsResponse.Homepage::getType, CurrentWsResponse.Homepage::getComponent) + .containsExactly(CurrentWsResponse.HomepageType.PORTFOLIO, portfolio.getKey()); + } + + @Test + public void return_homepage_when_set_to_an_application() { + ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization()); + UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter(application.uuid())); + userSessionRule.logIn(user); + + CurrentWsResponse response = call(); + + assertThat(response.getHomepage()) + .extracting(CurrentWsResponse.Homepage::getType, CurrentWsResponse.Homepage::getComponent) + .containsExactly(CurrentWsResponse.HomepageType.APPLICATION, application.getKey()); + } + @Test public void return_homepage_when_set_to_a_project() { ComponentDto project = db.components().insertPrivateProject(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java index 968cc706da2..4d221650f45 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java @@ -46,6 +46,7 @@ import static org.sonar.server.user.ws.HomepageTypes.Type.MY_PROJECTS; import static org.sonar.server.user.ws.HomepageTypes.Type.ORGANIZATION; import static org.sonar.server.user.ws.HomepageTypes.Type.PROJECT; import static org.sonar.server.user.ws.HomepageTypes.Type.PROJECTS; +import static org.sonar.server.user.ws.SetHomepageAction.PARAM_COMPONENT; import static org.sonar.server.user.ws.SetHomepageAction.PARAM_TYPE; public class SetHomepageActionTest { @@ -215,9 +216,6 @@ public class SetHomepageActionTest { @Test public void set_sonarqube_projects_homepage() { - when(homepageTypes.getTypes()).thenReturn(asList(PROJECT, ORGANIZATION, ISSUES, PROJECTS)); - ws = new WsActionTester(new SetHomepageAction(userSession, dbClient, TestComponentFinder.from(db))); - UserDto user = db.users().insertUser(); userSession.logIn(user); @@ -232,6 +230,60 @@ public class SetHomepageActionTest { assertThat(actual.getHomepageParameter()).isNullOrEmpty(); } + @Test + public void set_portfolios_homepage() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); + + ws.newRequest() + .setMethod("POST") + .setParam(PARAM_TYPE, "PORTFOLIOS") + .execute(); + + UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin()); + assertThat(actual).isNotNull(); + assertThat(actual.getHomepageType()).isEqualTo("PORTFOLIOS"); + assertThat(actual.getHomepageParameter()).isNullOrEmpty(); + } + + @Test + public void set_portfolio_homepage() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto portfolio = db.components().insertPrivatePortfolio(organization); + UserDto user = db.users().insertUser(); + userSession.logIn(user); + + ws.newRequest() + .setMethod("POST") + .setParam(PARAM_TYPE, "PORTFOLIO") + .setParam(PARAM_COMPONENT, portfolio.getKey()) + .execute(); + + UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin()); + assertThat(actual).isNotNull(); + assertThat(actual.getHomepageType()).isEqualTo("PORTFOLIO"); + assertThat(actual.getHomepageParameter()).isEqualTo(portfolio.uuid()); + } + + @Test + public void set_application_homepage() { + OrganizationDto organization = db.organizations().insert(); + ComponentDto application = db.components().insertPrivateApplication(organization); + UserDto user = db.users().insertUser(); + userSession.logIn(user); + + ws.newRequest() + .setMethod("POST") + .setParam(PARAM_TYPE, "APPLICATION") + .setParam(PARAM_COMPONENT, application.getKey()) + .execute(); + + UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin()); + assertThat(actual).isNotNull(); + assertThat(actual.getHomepageType()).isEqualTo("APPLICATION"); + assertThat(actual.getHomepageParameter()).isEqualTo(application.uuid()); + } + @Test public void response_has_no_content() { UserDto user = db.users().insertUser(); diff --git a/sonar-ws/src/main/protobuf/ws-users.proto b/sonar-ws/src/main/protobuf/ws-users.proto index 59b03221792..93c8b9bf755 100644 --- a/sonar-ws/src/main/protobuf/ws-users.proto +++ b/sonar-ws/src/main/protobuf/ws-users.proto @@ -121,6 +121,9 @@ message CurrentWsResponse { MY_ISSUES = 4; PROJECTS = 5; ISSUES = 6; + PORTFOLIO = 7; + PORTFOLIOS = 8; + APPLICATION = 9; } message Homepage { -- 2.39.5