From a5b62298cc4c67c0c7da81c97f874bf5d6be59d8 Mon Sep 17 00:00:00 2001 From: Mathieu Suen Date: Fri, 6 Mar 2020 12:09:56 +0100 Subject: [PATCH] SONAR-13146 Restore home select for portfolio. --- .../components/nav/component/HeaderMeta.tsx | 2 +- .../component/__tests__/HeaderMeta-test.tsx | 7 + .../__snapshots__/HeaderMeta-test.tsx.snap | 30 ++++ .../sonar/server/user/ws/CurrentAction.java | 50 +++--- .../sonar/server/user/ws/HomepageTypes.java | 14 +- .../server/user/ws/HomepageTypesImpl.java | 58 +------ .../server/user/ws/SetHomepageAction.java | 28 +--- .../user/ws/CurrentActionHomepageTest.java | 147 +++++++++--------- .../server/user/ws/CurrentActionTest.java | 13 +- .../server/user/ws/HomepageTypesImplTest.java | 74 +-------- .../server/user/ws/SetHomepageActionTest.java | 80 +--------- sonar-ws/src/main/protobuf/ws-users.proto | 16 +- 12 files changed, 170 insertions(+), 349 deletions(-) diff --git a/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx b/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx index 37c2ffcae46..ab8275d6b5e 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/HeaderMeta.tsx @@ -64,7 +64,7 @@ export function HeaderMeta(props: HeaderMetaProps) { component.version }`} )} - {isLoggedIn(currentUser) && isABranch && currentPage !== undefined && ( + {isLoggedIn(currentUser) && currentPage !== undefined && !isPullRequest(branchLike) && ( )} diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/HeaderMeta-test.tsx b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/HeaderMeta-test.tsx index 8aa31d61892..871ba889cee 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/HeaderMeta-test.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/HeaderMeta-test.tsx @@ -30,6 +30,13 @@ it('should render correctly for a branch', () => { expect(wrapper).toMatchSnapshot(); }); +it('should render correctly for a portfolio', () => { + const wrapper = shallowRender({ + component: mockComponent({ key: 'foo', qualifier: ComponentQualifier.Portfolio }) + }); + expect(wrapper).toMatchSnapshot(); +}); + it('should render correctly for a pull request', () => { const wrapper = shallowRender({ branchLike: mockPullRequest({ diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap index 82c0ef5bff9..60e7f6c630c 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/HeaderMeta-test.tsx.snap @@ -43,6 +43,36 @@ exports[`should render correctly for a branch 1`] = ` `; +exports[`should render correctly for a portfolio 1`] = ` + +
+ + + + +
+
+`; + exports[`should render correctly for a pull request 1`] = `
componentOptional) { - return !componentOptional.isPresent() || !pluginRepository.hasPlugin(GOVERNANCE_PLUGIN_KEY) + return !componentOptional.isPresent() || !hasValidEdition() || !userSession.hasComponentPermission(USER, componentOptional.get()); } - private Optional organizationHomepage(DbSession dbSession, UserDto user) { - Optional organizationOptional = dbClient.organizationDao().selectByUuid(dbSession, of(user.getHomepageParameter()).orElse(EMPTY)); - if (!organizationOptional.isPresent()) { - cleanUserHomepageInDb(dbSession, user); - return empty(); + private boolean hasValidEdition() { + Optional edition = editionProvider.get(); + if (!edition.isPresent()) { + return false; + } + switch (edition.get()) { + case ENTERPRISE: + case DATACENTER: + return true; + default: + return false; } - - return of(CurrentWsResponse.Homepage.newBuilder() - .setType(CurrentWsResponse.HomepageType.valueOf(user.getHomepageType())) - .setOrganization(organizationOptional.get().getKey()) - .build()); } private void cleanUserHomepageInDb(DbSession dbSession, UserDto user) { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypes.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypes.java index 2880bcfe9cf..e3fa9a94adc 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypes.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypes.java @@ -24,19 +24,7 @@ import java.util.List; public interface HomepageTypes { enum Type { - PROJECT, - /** - * These types are only available on SonarQube - */ - PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION, - /** - * These types are only available on SonarCloud - */ - MY_PROJECTS, MY_ISSUES, - /** - * This type is only available when organizations are enabled - */ - ORGANIZATION + PROJECT, PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION } List getTypes(); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java index fb108370440..9897bacfe80 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java @@ -19,41 +19,19 @@ */ package org.sonar.server.user.ws; -import java.util.EnumSet; import java.util.List; -import org.sonar.api.Startable; -import org.sonar.api.config.Configuration; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.process.ProcessProperties; -import org.sonar.server.organization.OrganizationFlags; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.google.common.base.Preconditions.checkState; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toList; -import static org.sonar.server.user.ws.HomepageTypes.Type.ISSUES; -import static org.sonar.server.user.ws.HomepageTypes.Type.MY_ISSUES; -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.HomepageTypes.Type.values; -public class HomepageTypesImpl implements HomepageTypes, Startable { - - private static final EnumSet ON_SONARQUBE = EnumSet.of(PROJECTS, PROJECT, ISSUES, ORGANIZATION); - private static final EnumSet ON_SONARCLOUD = EnumSet.of(PROJECT, MY_PROJECTS, MY_ISSUES, ORGANIZATION); - - private final Configuration configuration; - private final OrganizationFlags organizationFlags; - private final DbClient dbClient; +public class HomepageTypesImpl implements HomepageTypes { private List types; - public HomepageTypesImpl(Configuration configuration, OrganizationFlags organizationFlags, DbClient dbClient) { - this.configuration = configuration; - this.organizationFlags = organizationFlags; - this.dbClient = dbClient; + public HomepageTypesImpl() { + types = Stream.of(HomepageTypes.Type.values()).collect(Collectors.toList()); } @Override @@ -64,31 +42,7 @@ public class HomepageTypesImpl implements HomepageTypes, Startable { @Override public Type getDefaultType() { - return isOnSonarCloud() ? MY_PROJECTS : PROJECTS; - } - - @Override - public void start() { - try (DbSession dbSession = dbClient.openSession(false)) { - boolean isOnSonarCloud = isOnSonarCloud(); - boolean isOrganizationEnabled = isOrganizationEnabled(dbSession); - this.types = stream(values()) - .filter(type -> (isOnSonarCloud && ON_SONARCLOUD.contains(type)) || (!isOnSonarCloud && ON_SONARQUBE.contains(type))) - .filter(type -> isOrganizationEnabled || !(type.equals(ORGANIZATION))) - .collect(toList()); - } + return PROJECTS; } - private boolean isOrganizationEnabled(DbSession dbSession) { - return organizationFlags.isEnabled(dbSession); - } - - private Boolean isOnSonarCloud() { - return configuration.getBoolean(ProcessProperties.Property.SONARCLOUD_ENABLED.getKey()).orElse(false); - } - - @Override - public void stop() { - // Nothing to do - } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java index eaa1c2fa1a3..053f1d520d1 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java @@ -30,15 +30,12 @@ import org.sonar.db.DbSession; import org.sonar.db.project.ProjectDto; import org.sonar.db.user.UserDto; import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static java.lang.String.format; -import static org.apache.commons.lang.StringUtils.isBlank; import static org.apache.commons.lang.StringUtils.isNotBlank; -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.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; @@ -71,7 +68,10 @@ public class SetHomepageAction implements UsersWsAction { .setDescription("Set homepage of current user.
" + "Requires authentication.") .setSince("7.0") - .setChangelog(new Change("7.1", "Parameter 'parameter' is replaced by 'component' and 'organization'")) + .setChangelog( + new Change("8.3", "Types: MY_PROJECTS, MY_ISSUES, ORGANIZATION removed"), + new Change("8.3", "Parameter 'organization' removed"), + new Change("7.1", "Parameter 'parameter' is replaced by 'component' and 'organization'")) .setHandler(this); action.createParam(PARAM_TYPE) @@ -79,11 +79,6 @@ public class SetHomepageAction implements UsersWsAction { .setRequired(true) .setPossibleValues(HomepageTypes.Type.values()); - action.createParam(PARAM_ORGANIZATION) - .setDescription("Organization key. It should only be used when parameter '%s' is set to '%s'", PARAM_TYPE, ORGANIZATION) - .setSince("7.1") - .setExampleValue("my-org"); - action.createParam(PARAM_COMPONENT) .setSince("7.1") .setDescription("Project key. It should only be used when parameter '%s' is set to '%s'", PARAM_TYPE, PROJECT) @@ -100,10 +95,9 @@ public class SetHomepageAction implements UsersWsAction { userSession.checkLoggedIn(); HomepageTypes.Type type = request.mandatoryParamAsEnum(PARAM_TYPE, HomepageTypes.Type.class); String componentParameter = request.param(PARAM_COMPONENT); - String organizationParameter = request.param(PARAM_ORGANIZATION); try (DbSession dbSession = dbClient.openSession(false)) { - String parameter = getHomepageParameter(dbSession, type, componentParameter, request.param(PARAM_BRANCH), organizationParameter); + String parameter = getHomepageParameter(dbSession, type, componentParameter, request.param(PARAM_BRANCH)); UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, userSession.getLogin()); checkState(user != null, "User login '%s' cannot be found", userSession.getLogin()); @@ -118,8 +112,7 @@ public class SetHomepageAction implements UsersWsAction { } @CheckForNull - private String getHomepageParameter(DbSession dbSession, HomepageTypes.Type type, @Nullable String componentParameter, @Nullable String branchParameter, - @Nullable String organizationParameter) { + private String getHomepageParameter(DbSession dbSession, HomepageTypes.Type type, @Nullable String componentParameter, @Nullable String branchParameter) { switch (type) { case PROJECT: checkArgument(isNotBlank(componentParameter), PARAMETER_REQUIRED, type.name(), PARAM_COMPONENT); @@ -133,18 +126,9 @@ public class SetHomepageAction implements UsersWsAction { case APPLICATION: checkArgument(isNotBlank(componentParameter), PARAMETER_REQUIRED, type.name(), PARAM_COMPONENT); return componentFinder.getByKey(dbSession, componentParameter).uuid(); - case 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: - case MY_ISSUES: - checkArgument(isBlank(componentParameter), "Parameter '%s' must not be provided when type is '%s'", PARAM_COMPONENT, type.name()); - checkArgument(isBlank(organizationParameter), "Parameter '%s' must not be provided when type is '%s'", PARAM_ORGANIZATION, type.name()); return null; default: throw new IllegalArgumentException(format("Unknown type '%s'", type.name())); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionHomepageTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionHomepageTest.java index 3f26477d290..5c05c4f650d 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionHomepageTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionHomepageTest.java @@ -19,25 +19,29 @@ */ package org.sonar.server.user.ws; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import java.util.Optional; +import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.config.internal.MapSettings; +import org.junit.runner.RunWith; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.ResourceType; import org.sonar.api.resources.ResourceTypeTree; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.utils.System2; -import org.sonar.core.platform.PluginRepository; +import org.sonar.core.platform.EditionProvider; +import org.sonar.core.platform.PlatformEditionProvider; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; import org.sonar.db.user.UserDto; import org.sonar.server.issue.AvatarResolverImpl; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.organization.TestOrganizationFlags; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.tester.UserSessionRule; @@ -48,7 +52,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.api.web.UserRole.USER; +import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PROJECTS; +@RunWith(DataProviderRunner.class) public class CurrentActionHomepageTest { @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); @@ -60,27 +66,13 @@ public class CurrentActionHomepageTest { private DbClient dbClient = db.getDbClient(); private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - private PluginRepository pluginRepository = mock(PluginRepository.class); - private MapSettings settings = new MapSettings(); - private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone(); - private HomepageTypesImpl homepageTypes = new HomepageTypesImpl(settings.asConfig(), organizationFlags, db.getDbClient()); + private PlatformEditionProvider platformEditionProvider = mock(PlatformEditionProvider.class); + private HomepageTypesImpl homepageTypes = new HomepageTypesImpl(); private PermissionService permissionService = new PermissionServiceImpl(new ResourceTypes(new ResourceTypeTree[] { ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.PROJECT).build()).build()})); private WsActionTester ws = new WsActionTester( - new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl(), homepageTypes, pluginRepository, permissionService)); - - @Test - public void return_homepage_when_set_to_MY_PROJECTS() { - UserDto user = db.users().insertUser(u -> u.setHomepageType("MY_PROJECTS")); - userSessionRule.logIn(user); - - CurrentWsResponse response = call(); - - assertThat(response.getHomepage()) - .extracting(CurrentWsResponse.Homepage::getType) - .isEqualTo(CurrentWsResponse.HomepageType.MY_PROJECTS); - } + new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl(), homepageTypes, platformEditionProvider, permissionService)); @Test public void return_homepage_when_set_to_portfolios() { @@ -95,8 +87,9 @@ public class CurrentActionHomepageTest { } @Test - public void return_homepage_when_set_to_a_portfolio() { - withGovernancePlugin(); + @UseDataProvider("enterpriseAndAbove") + public void return_homepage_when_set_to_a_portfolio(EditionProvider.Edition edition) { + setPlatformEdition(edition); ComponentDto portfolio = db.components().insertPrivatePortfolio(db.getDefaultOrganization()); UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIO").setHomepageParameter(portfolio.uuid())); userSessionRule.logIn(user).addProjectPermission(USER, portfolio); @@ -109,8 +102,9 @@ public class CurrentActionHomepageTest { } @Test - public void return_default_when_set_to_a_portfolio_but_no_rights_on_this_portfolio() { - withGovernancePlugin(); + @UseDataProvider("enterpriseAndAbove") + public void return_default_when_set_to_a_portfolio_but_no_rights_on_this_portfolio(EditionProvider.Edition edition) { + setPlatformEdition(edition); ComponentDto portfolio = db.components().insertPrivatePortfolio(db.getDefaultOrganization()); UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIO").setHomepageParameter(portfolio.uuid())); userSessionRule.logIn(user); @@ -119,12 +113,13 @@ public class CurrentActionHomepageTest { assertThat(response.getHomepage()) .extracting(CurrentWsResponse.Homepage::getType) - .isEqualTo(CurrentWsResponse.HomepageType.PROJECTS); + .isEqualTo(PROJECTS); } @Test - public void return_homepage_when_set_to_an_application() { - withGovernancePlugin(); + @UseDataProvider("enterpriseAndAbove") + public void return_homepage_when_set_to_an_application(EditionProvider.Edition edition) { + setPlatformEdition(edition); ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization()); UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter(application.uuid())); userSessionRule.logIn(user).addProjectPermission(USER, application); @@ -137,8 +132,9 @@ public class CurrentActionHomepageTest { } @Test - public void return_default_homepage_when_set_to_an_application_but_no_rights_on_this_application() { - withGovernancePlugin(); + @UseDataProvider("enterpriseAndAbove") + public void return_default_homepage_when_set_to_an_application_but_no_rights_on_this_application(EditionProvider.Edition edition) { + setPlatformEdition(edition); ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization()); UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter(application.uuid())); userSessionRule.logIn(user); @@ -147,11 +143,13 @@ public class CurrentActionHomepageTest { assertThat(response.getHomepage()) .extracting(CurrentWsResponse.Homepage::getType) - .isEqualTo(CurrentWsResponse.HomepageType.PROJECTS); + .isEqualTo(PROJECTS); } @Test - public void return_homepage_when_set_to_a_project() { + @UseDataProvider("allEditions") + public void return_homepage_when_set_to_a_project(EditionProvider.Edition edition) { + setPlatformEdition(edition); ComponentDto project = db.components().insertPrivateProject(); UserDto user = db.users().insertUser(u -> u.setHomepageType("PROJECT").setHomepageParameter(project.uuid())); userSessionRule.logIn(user).addProjectPermission(USER, project); @@ -164,7 +162,9 @@ public class CurrentActionHomepageTest { } @Test - public void return_default_homepage_when_set_to_a_project_but_no_rights_on_this_project() { + @UseDataProvider("allEditions") + public void return_default_homepage_when_set_to_a_project_but_no_rights_on_this_project(EditionProvider.Edition edition) { + setPlatformEdition(edition); ComponentDto project = db.components().insertPrivateProject(); UserDto user = db.users().insertUser(u -> u.setHomepageType("PROJECT").setHomepageParameter(project.uuid())); userSessionRule.logIn(user); @@ -173,20 +173,7 @@ public class CurrentActionHomepageTest { assertThat(response.getHomepage()) .extracting(CurrentWsResponse.Homepage::getType) - .isEqualTo(CurrentWsResponse.HomepageType.PROJECTS); - } - - @Test - public void return_homepage_when_set_to_an_organization() { - OrganizationDto organizationDto = db.organizations().insert(); - UserDto user = db.users().insertUser(u -> u.setHomepageType("ORGANIZATION").setHomepageParameter(organizationDto.getUuid())); - userSessionRule.logIn(user); - - CurrentWsResponse response = call(); - - assertThat(response.getHomepage()) - .extracting(CurrentWsResponse.Homepage::getType, CurrentWsResponse.Homepage::getOrganization) - .containsExactly(CurrentWsResponse.HomepageType.ORGANIZATION, organizationDto.getKey()); + .isEqualTo(PROJECTS); } @Test @@ -214,8 +201,10 @@ public class CurrentActionHomepageTest { } @Test - public void fallback_when_user_homepage_organization_does_not_exist_in_db() { - UserDto user = db.users().insertUser(u -> u.setHomepageType("ORGANIZATION").setHomepageParameter("not-existing-organization-uuid")); + @UseDataProvider("enterpriseAndAbove") + public void fallback_when_user_homepage_portfolio_does_not_exist_in_db(EditionProvider.Edition edition) { + setPlatformEdition(edition); + UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIO").setHomepageParameter("not-existing-portfolio-uuid")); userSessionRule.logIn(user.getLogin()); CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class); @@ -224,19 +213,22 @@ public class CurrentActionHomepageTest { } @Test - public void fallback_when_user_homepage_portfolio_does_not_exist_in_db() { - withGovernancePlugin(); - UserDto user = db.users().insertUser(u -> u.setHomepageType("PORTFOLIO").setHomepageParameter("not-existing-portfolio-uuid")); + public void fallback_when_edition_is_null() { + setPlatformEdition(null); + ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization()); + UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter(application.uuid())); userSessionRule.logIn(user.getLogin()); CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class); assertThat(response.getHomepage()).isNotNull(); + assertThat(response.getHomepage().getType()).isEqualTo(PROJECTS); } @Test - public void fallback_when_user_homepage_application_does_not_exist_in_db() { - withGovernancePlugin(); + @UseDataProvider("enterpriseAndAbove") + public void fallback_when_user_homepage_application_does_not_exist_in_db(EditionProvider.Edition edition) { + setPlatformEdition(edition); UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter("not-existing-application-uuid")); userSessionRule.logIn(user.getLogin()); @@ -246,8 +238,9 @@ public class CurrentActionHomepageTest { } @Test - public void fallback_when_user_homepage_application_and_governance_plugin_is_not_installed() { - withoutGovernancePlugin(); + @UseDataProvider("belowEnterprise") + public void fallback_when_user_homepage_application_and_edition_below_enterprise(EditionProvider.Edition edition) { + setPlatformEdition(edition); ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization()); UserDto user = db.users().insertUser(u -> u.setHomepageType("APPLICATION").setHomepageParameter(application.uuid())); userSessionRule.logIn(user.getLogin()); @@ -258,7 +251,7 @@ public class CurrentActionHomepageTest { } @Test - public void fallback_to_PROJECTS_when_on_SonarQube() { + public void fallback_to_PROJECTS() { UserDto user = db.users().insertUser(u -> u.setHomepageType("PROJECT").setHomepageParameter("not-existing-project-uuid")); userSessionRule.logIn(user.getLogin()); @@ -267,31 +260,37 @@ public class CurrentActionHomepageTest { assertThat(response.getHomepage().getType().toString()).isEqualTo("PROJECTS"); } - @Test - public void fallback_to_MY_PROJECTS_when_on_SonarCloud() { - onSonarCloud(); - UserDto user = db.users().insertUser(u -> u.setHomepageType("PROJECT").setHomepageParameter("not-existing-project-uuid")); - userSessionRule.logIn(user.getLogin()); - - CurrentWsResponse response = ws.newRequest().executeProtobuf(CurrentWsResponse.class); - - assertThat(response.getHomepage().getType().toString()).isEqualTo("MY_PROJECTS"); - } - private CurrentWsResponse call() { return ws.newRequest().executeProtobuf(CurrentWsResponse.class); } - private void onSonarCloud() { - settings.setProperty("sonar.sonarcloud.enabled", true); + private void setPlatformEdition(@Nullable EditionProvider.Edition edition) { + when(platformEditionProvider.get()).thenReturn(Optional.ofNullable(edition)); } - private void withGovernancePlugin() { - when(pluginRepository.hasPlugin("governance")).thenReturn(true); + @DataProvider + public static Object[][] enterpriseAndAbove() { + return new Object[][] { + {EditionProvider.Edition.ENTERPRISE}, + {EditionProvider.Edition.DATACENTER} + }; } - private void withoutGovernancePlugin() { - when(pluginRepository.hasPlugin("governance")).thenReturn(false); + @DataProvider + public static Object[][] belowEnterprise() { + return new Object[][] { + {EditionProvider.Edition.COMMUNITY}, + {EditionProvider.Edition.DEVELOPER} + }; } + @DataProvider + public static Object[][] allEditions() { + return new Object[][] { + {EditionProvider.Edition.COMMUNITY}, + {EditionProvider.Edition.DEVELOPER}, + {EditionProvider.Edition.ENTERPRISE}, + {EditionProvider.Edition.DATACENTER} + }; + } } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java index 45388da735e..92e6dd1ad6b 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java @@ -23,20 +23,18 @@ import java.util.Collections; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sonar.api.config.internal.MapSettings; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.ResourceType; import org.sonar.api.resources.ResourceTypeTree; import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.core.platform.PluginRepository; +import org.sonar.core.platform.PlatformEditionProvider; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.user.UserDto; import org.sonar.server.issue.AvatarResolverImpl; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.organization.TestOrganizationFlags; import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionServiceImpl; import org.sonar.server.tester.UserSessionRule; @@ -63,15 +61,14 @@ public class CurrentActionTest { @Rule public ExpectedException expectedException = ExpectedException.none(); - private PluginRepository pluginRepository = mock(PluginRepository.class); - private MapSettings settings = new MapSettings(); - private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone(); - private HomepageTypesImpl homepageTypes = new HomepageTypesImpl(settings.asConfig(), organizationFlags, db.getDbClient()); + private PlatformEditionProvider platformEditionProvider = mock(PlatformEditionProvider.class); + private HomepageTypesImpl homepageTypes = new HomepageTypesImpl(); private PermissionService permissionService = new PermissionServiceImpl(new ResourceTypes(new ResourceTypeTree[] { ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.PROJECT).build()).build()})); private WsActionTester ws = new WsActionTester( - new CurrentAction(userSession, db.getDbClient(), TestDefaultOrganizationProvider.from(db), new AvatarResolverImpl(), homepageTypes, pluginRepository, permissionService)); + new CurrentAction(userSession, db.getDbClient(), TestDefaultOrganizationProvider.from(db), new AvatarResolverImpl(), homepageTypes, platformEditionProvider, + permissionService)); @Test public void return_user_info() { diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java index 0c642ea6f9e..8e6a43feee8 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java @@ -19,85 +19,27 @@ */ package org.sonar.server.user.ws; -import org.junit.Rule; import org.junit.Test; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.db.DbTester; -import org.sonar.server.organization.TestOrganizationFlags; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.user.ws.HomepageTypes.Type.APPLICATION; import static org.sonar.server.user.ws.HomepageTypes.Type.ISSUES; -import static org.sonar.server.user.ws.HomepageTypes.Type.MY_ISSUES; -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.PORTFOLIO; +import static org.sonar.server.user.ws.HomepageTypes.Type.PORTFOLIOS; import static org.sonar.server.user.ws.HomepageTypes.Type.PROJECT; import static org.sonar.server.user.ws.HomepageTypes.Type.PROJECTS; public class HomepageTypesImplTest { - @Rule - public DbTester db = DbTester.create(); - - private MapSettings settings = new MapSettings(); - private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone(); - - private HomepageTypesImpl underTest = new HomepageTypesImpl(settings.asConfig(), organizationFlags, db.getDbClient()); - - @Test - public void types_on_sonarcloud_and_organization_disabled() { - settings.setProperty("sonar.sonarcloud.enabled", true); - organizationFlags.setEnabled(false); - - underTest.start(); - - assertThat(underTest.getTypes()).containsExactlyInAnyOrder(PROJECT, MY_PROJECTS, MY_ISSUES); - } - - @Test - public void types_on_sonarcloud_and_organization_enabled() { - settings.setProperty("sonar.sonarcloud.enabled", true); - organizationFlags.setEnabled(true); - - underTest.start(); - - assertThat(underTest.getTypes()).containsExactlyInAnyOrder(PROJECT, MY_PROJECTS, MY_ISSUES, ORGANIZATION); - } - - @Test - public void types_on_sonarqube_and_organization_disabled() { - settings.setProperty("sonar.sonarcloud.enabled", false); - organizationFlags.setEnabled(false); - - underTest.start(); - - assertThat(underTest.getTypes()).containsExactlyInAnyOrder(PROJECT, PROJECTS, ISSUES); - } + private HomepageTypesImpl underTest = new HomepageTypesImpl(); @Test - public void types_on_sonarqube_and_organization_enabled() { - settings.setProperty("sonar.sonarcloud.enabled", false); - organizationFlags.setEnabled(true); - - underTest.start(); - - assertThat(underTest.getTypes()).containsExactlyInAnyOrder(PROJECT, PROJECTS, ISSUES, ORGANIZATION); + public void types() { + assertThat(underTest.getTypes()).containsExactlyInAnyOrder(PROJECT, PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION); } @Test - public void default_type_on_sonarcloud() { - settings.setProperty("sonar.sonarcloud.enabled", true); - - underTest.start(); - - assertThat(underTest.getDefaultType()).isEqualTo(MY_PROJECTS); - } - - @Test - public void default_type_on_sonarqube() { - settings.setProperty("sonar.sonarcloud.enabled", false); - - underTest.start(); - + public void default_type() { assertThat(underTest.getDefaultType()).isEqualTo(PROJECTS); } diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java index d2335d16e74..e6c5801bdfd 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java @@ -63,7 +63,7 @@ public class SetHomepageActionTest { assertThat(action.since()).isEqualTo("7.0"); assertThat(action.description()).isEqualTo("Set homepage of current user.
Requires authentication."); assertThat(action.responseExample()).isNull(); - assertThat(action.params()).hasSize(4); + assertThat(action.params()).hasSize(3); WebService.Param typeParam = action.param("type"); assertThat(typeParam.isRequired()).isTrue(); @@ -78,11 +78,6 @@ public class SetHomepageActionTest { assertThat(branchParam.isRequired()).isFalse(); assertThat(branchParam.description()).isEqualTo("Branch key. It can only be used when parameter 'type' is set to 'PROJECT'"); assertThat(branchParam.since()).isEqualTo("7.1"); - - WebService.Param organizationParam = action.param("organization"); - assertThat(organizationParam.isRequired()).isFalse(); - assertThat(organizationParam.description()).isEqualTo("Organization key. It should only be used when parameter 'type' is set to 'ORGANIZATION'"); - assertThat(organizationParam.since()).isEqualTo("7.1"); } @Test @@ -127,42 +122,7 @@ public class SetHomepageActionTest { } @Test - public void set_organization_homepage() { - OrganizationDto organization = db.organizations().insert(); - - UserDto user = db.users().insertUser(); - userSession.logIn(user); - - ws.newRequest() - .setMethod("POST") - .setParam(PARAM_TYPE, "ORGANIZATION") - .setParam("organization", organization.getKey()) - .execute(); - - UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin()); - assertThat(actual).isNotNull(); - assertThat(actual.getHomepageType()).isEqualTo("ORGANIZATION"); - assertThat(actual.getHomepageParameter()).isEqualTo(organization.getUuid()); - } - - @Test - public void set_SonarCloud_my_issues_homepage() { - UserDto user = db.users().insertUser(); - userSession.logIn(user); - - ws.newRequest() - .setMethod("POST") - .setParam(PARAM_TYPE, "MY_ISSUES") - .execute(); - - UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin()); - assertThat(actual).isNotNull(); - assertThat(actual.getHomepageType()).isEqualTo("MY_ISSUES"); - assertThat(actual.getHomepageParameter()).isNullOrEmpty(); - } - - @Test - public void set_SonarQube_issues_homepage() { + public void set_issues_homepage() { UserDto user = db.users().insertUser(); userSession.logIn(user); @@ -179,23 +139,7 @@ public class SetHomepageActionTest { } @Test - public void set_SonarCloud_my_projects_homepage() { - UserDto user = db.users().insertUser(); - userSession.logIn(user); - - ws.newRequest() - .setMethod("POST") - .setParam(PARAM_TYPE, "MY_PROJECTS") - .execute(); - - UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin()); - assertThat(actual).isNotNull(); - assertThat(actual.getHomepageType()).isEqualTo("MY_PROJECTS"); - assertThat(actual.getHomepageParameter()).isNullOrEmpty(); - } - - @Test - public void set_SonarQube_projects_homepage() { + public void set_projects_homepage() { UserDto user = db.users().insertUser(); userSession.logIn(user); @@ -271,7 +215,7 @@ public class SetHomepageActionTest { TestResponse response = ws.newRequest() .setMethod("POST") - .setParam(PARAM_TYPE, "MY_PROJECTS") + .setParam(PARAM_TYPE, "PROJECTS") .execute(); assertThat(response.getStatus()).isEqualTo(SC_NO_CONTENT); @@ -293,20 +237,6 @@ public class SetHomepageActionTest { } - @Test - public void fail_when_missing_organization_id_when_requesting_organization_type() { - UserDto user = db.users().insertUser(); - userSession.logIn(user); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Type ORGANIZATION requires a parameter"); - - ws.newRequest() - .setMethod("POST") - .setParam(PARAM_TYPE, "ORGANIZATION") - .execute(); - } - @Test public void fail_when_invalid_homepage_type() { UserDto user = db.users().insertUser(); @@ -314,7 +244,7 @@ public class SetHomepageActionTest { expectedException.expect(IllegalArgumentException.class); expectedException - .expectMessage("Value of parameter 'type' (PIPO) must be one of: [PROJECT, PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION, MY_PROJECTS, MY_ISSUES, ORGANIZATION]"); + .expectMessage("Value of parameter 'type' (PIPO) must be one of: [PROJECT, PROJECTS, ISSUES, PORTFOLIOS, PORTFOLIO, APPLICATION]"); ws.newRequest() .setMethod("POST") diff --git a/sonar-ws/src/main/protobuf/ws-users.proto b/sonar-ws/src/main/protobuf/ws-users.proto index b42b8a2abe0..a12b035594f 100644 --- a/sonar-ws/src/main/protobuf/ws-users.proto +++ b/sonar-ws/src/main/protobuf/ws-users.proto @@ -118,21 +118,17 @@ message CurrentWsResponse { enum HomepageType { PROJECT = 1; - ORGANIZATION = 2; - MY_PROJECTS = 3; - MY_ISSUES = 4; - PROJECTS = 5; - ISSUES = 6; - PORTFOLIO = 7; - PORTFOLIOS = 8; - APPLICATION = 9; + PROJECTS = 2; + ISSUES = 3; + PORTFOLIO = 4; + PORTFOLIOS = 5; + APPLICATION = 6; } message Homepage { optional HomepageType type = 1; optional string component = 2; - optional string organization = 3; - optional string branch = 4; + optional string branch = 3; } message Setting { -- 2.39.5