From b035b76e5e7f6a537c00681450f4f7a5605a1026 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 15 Feb 2018 10:33:33 +0100 Subject: [PATCH] SONAR-10423 Allow homepage feature on SonarQube --- .../sonar/server/user/ws/CurrentAction.java | 9 +- .../{HomepageType.java => HomepageTypes.java} | 25 +++-- .../server/user/ws/HomepageTypesImpl.java | 89 +++++++++++++++ .../server/user/ws/SetHomepageAction.java | 16 +-- .../sonar/server/user/ws/UsersWsModule.java | 3 +- .../server/user/ws/CurrentActionTest.java | 16 ++- .../server/user/ws/HomepageTypesImplTest.java | 104 ++++++++++++++++++ .../server/user/ws/SetHomepageActionTest.java | 20 +++- .../server/user/ws/UsersWsModuleTest.java | 2 +- .../org/sonar/server/user/ws/UsersWsTest.java | 12 +- sonar-ws/src/main/protobuf/ws-users.proto | 1 + .../sonarqube/tests/user/HomepageTest.java | 93 ++++++++++++++++ .../org/sonarqube/tests/user/UserSuite.java | 1 + 13 files changed, 353 insertions(+), 38 deletions(-) rename server/sonar-server/src/main/java/org/sonar/server/user/ws/{HomepageType.java => HomepageTypes.java} (70%) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java create mode 100644 tests/src/test/java/org/sonarqube/tests/user/HomepageTest.java 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 588af51c919..cb959d11605 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,6 @@ 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.MY_PROJECTS; import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.ORGANIZATION; import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PROJECT; import static org.sonarqube.ws.client.user.UsersWsParameters.ACTION_CURRENT; @@ -57,13 +56,15 @@ public class CurrentAction implements UsersWsAction { private final DbClient dbClient; private final DefaultOrganizationProvider defaultOrganizationProvider; private final AvatarResolver avatarResolver; + private final HomepageTypes homepageTypes; public CurrentAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, - AvatarResolver avatarResolver) { + AvatarResolver avatarResolver, HomepageTypes homepageTypes) { this.userSession = userSession; this.dbClient = dbClient; this.defaultOrganizationProvider = defaultOrganizationProvider; this.avatarResolver = avatarResolver; + this.homepageTypes = homepageTypes; } @Override @@ -154,9 +155,9 @@ public class CurrentAction implements UsersWsAction { } } - private static CurrentWsResponse.Homepage defaultHomepage() { + private CurrentWsResponse.Homepage defaultHomepage() { return CurrentWsResponse.Homepage.newBuilder() - .setType(MY_PROJECTS) + .setType(CurrentWsResponse.HomepageType.valueOf(homepageTypes.getDefaultType().name())) .build(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageType.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java similarity index 70% rename from server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageType.java rename to server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java index b2ada366b95..cd811d67f1d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageType.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java @@ -21,14 +21,25 @@ package org.sonar.server.user.ws; import java.util.List; -import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toList; +public interface HomepageTypes { -public enum HomepageType { + enum Type { + PROJECT, + /** + * This type in only available on SonarQube + */ + PROJECTS, + /** + * These types are only available on SonarCloud + */ + MY_PROJECTS, MY_ISSUES, + /** + * This type in only available when organizations are enabled + */ + ORGANIZATION + } - PROJECT, ORGANIZATION, MY_PROJECTS, MY_ISSUES; + List getTypes(); - public static List keys() { - return stream(values()).map(Enum::toString).collect(toList()); - } + Type getDefaultType(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java new file mode 100644 index 00000000000..026cc0bdc6f --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java @@ -0,0 +1,89 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +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 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.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, 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; + + private List types; + private Type defaultType; + + public HomepageTypesImpl(Configuration configuration, OrganizationFlags organizationFlags, DbClient dbClient) { + this.configuration = configuration; + this.organizationFlags = organizationFlags; + this.dbClient = dbClient; + } + + @Override + public List getTypes() { + checkState(types != null, "Homepage types have not been initialized yet"); + return types; + } + + @Override + public Type getDefaultType() { + checkState(types != null, "Homepage types have not been initialized yet"); + return defaultType; + } + + @Override + public void start() { + try (DbSession dbSession = dbClient.openSession(false)) { + boolean isOnSonarCloud = configuration.getBoolean(ProcessProperties.Property.SONARCLOUD_ENABLED.getKey()).orElse(false); + boolean isOrganizationEnabled = organizationFlags.isEnabled(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()); + this.defaultType = isOnSonarCloud ? Type.MY_PROJECTS : PROJECTS; + } + } + + @Override + public void stop() { + // Nothing to do + } +} 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 d802cd6bcc3..4765058dc95 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 @@ -37,10 +37,8 @@ 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.HomepageType.ORGANIZATION; -import static org.sonar.server.user.ws.HomepageType.PROJECT; -import static org.sonar.server.user.ws.HomepageType.keys; -import static org.sonar.server.user.ws.HomepageType.valueOf; +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; @@ -56,11 +54,13 @@ public class SetHomepageAction implements UsersWsAction { private final UserSession userSession; private final DbClient dbClient; private final ComponentFinder componentFinder; + private HomepageTypes homepageTypes; - public SetHomepageAction(UserSession userSession, DbClient dbClient, ComponentFinder componentFinder) { + public SetHomepageAction(UserSession userSession, DbClient dbClient, ComponentFinder componentFinder, HomepageTypes homepageTypes) { this.userSession = userSession; this.dbClient = dbClient; this.componentFinder = componentFinder; + this.homepageTypes = homepageTypes; } @Override @@ -77,7 +77,7 @@ public class SetHomepageAction implements UsersWsAction { action.createParam(PARAM_TYPE) .setDescription("Type of the requested page") .setRequired(true) - .setPossibleValues(keys()); + .setPossibleValues(homepageTypes.getTypes()); action.createParam(PARAM_ORGANIZATION) .setDescription("Organization key. It should only be used when parameter '%s' is set to '%s'", PARAM_TYPE, ORGANIZATION) @@ -100,7 +100,7 @@ public class SetHomepageAction implements UsersWsAction { @Override public void handle(Request request, Response response) throws Exception { userSession.checkLoggedIn(); - HomepageType type = valueOf(request.mandatoryParam(PARAM_TYPE)); + HomepageTypes.Type type = request.mandatoryParamAsEnum(PARAM_TYPE, HomepageTypes.Type.class); String componentParameter = request.param(PARAM_COMPONENT); String organizationParameter = request.param(PARAM_ORGANIZATION); @@ -120,7 +120,7 @@ public class SetHomepageAction implements UsersWsAction { } @CheckForNull - private String getHomepageParameter(DbSession dbSession, HomepageType type, @Nullable String componentParameter, @Nullable String branchParameter, + private String getHomepageParameter(DbSession dbSession, HomepageTypes.Type type, @Nullable String componentParameter, @Nullable String branchParameter, @Nullable String organizationParameter) { switch (type) { case PROJECT: diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java index d1bec855ed6..39d6c3ae5de 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java @@ -37,6 +37,7 @@ public class UsersWsModule extends Module { UserPropertiesWs.class, UserJsonWriter.class, SkipOnboardingTutorialAction.class, - SetHomepageAction.class); + SetHomepageAction.class, + HomepageTypesImpl.class); } } 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 8d58daa38a5..9f83fce0273 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 @@ -19,6 +19,7 @@ */ package org.sonar.server.user.ws; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -37,13 +38,14 @@ import org.sonarqube.ws.Users.CurrentWsResponse; import static com.google.common.collect.Lists.newArrayList; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS; import static org.sonar.db.permission.OrganizationPermission.SCAN; import static org.sonar.db.user.GroupTesting.newGroupDto; import static org.sonar.test.JsonAssert.assertJson; -import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.MY_PROJECTS; public class CurrentActionTest { @Rule @@ -55,7 +57,15 @@ public class CurrentActionTest { private DbClient dbClient = db.getDbClient(); private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - private WsActionTester ws = new WsActionTester(new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl())); + private HomepageTypes homepageTypes = mock(HomepageTypes.class); + + private WsActionTester ws = new WsActionTester(new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl(), homepageTypes)); + + @Before + public void setUp() { + when(homepageTypes.getDefaultType()).thenReturn(HomepageTypes.Type.MY_PROJECTS); + ws = new WsActionTester(new CurrentAction(userSessionRule, dbClient, defaultOrganizationProvider, new AvatarResolverImpl(), homepageTypes)); + } @Test public void return_user_info() { @@ -153,7 +163,7 @@ public class CurrentActionTest { assertThat(response.getHomepage()) .extracting(CurrentWsResponse.Homepage::getType) - .containsExactly(MY_PROJECTS); + .containsExactly(CurrentWsResponse.HomepageType.MY_PROJECTS); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java new file mode 100644 index 00000000000..e6c9bf7aa77 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java @@ -0,0 +1,104 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +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.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; + +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); + } + + @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, ORGANIZATION); + } + + @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(); + + assertThat(underTest.getDefaultType()).isEqualTo(PROJECTS); + } + +} 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 aca3fd2a672..d04b170d893 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 @@ -19,6 +19,7 @@ */ package org.sonar.server.user.ws; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -34,8 +35,15 @@ import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; +import static java.util.Arrays.asList; import static org.apache.http.HttpStatus.SC_NO_CONTENT; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +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; public class SetHomepageActionTest { @@ -49,8 +57,15 @@ public class SetHomepageActionTest { public ExpectedException expectedException = ExpectedException.none(); private DbClient dbClient = db.getDbClient(); - private SetHomepageAction underTest = new SetHomepageAction(userSession, dbClient, TestComponentFinder.from(db)); - private WsActionTester ws = new WsActionTester(underTest); + private HomepageTypes homepageTypes = mock(HomepageTypes.class); + + private WsActionTester ws; + + @Before + public void setUp() { + when(homepageTypes.getTypes()).thenReturn(asList(PROJECT, ORGANIZATION, MY_ISSUES, MY_PROJECTS)); + ws = new WsActionTester(new SetHomepageAction(userSession, dbClient, TestComponentFinder.from(db), homepageTypes)); + } @Test public void verify_definition() { @@ -61,7 +76,6 @@ 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.handler()).isSameAs(underTest); assertThat(action.params()).hasSize(4); WebService.Param typeParam = action.param("type"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java index 443722be3d8..ad4e8668dd5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java @@ -29,6 +29,6 @@ public class UsersWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new UsersWsModule().configure(container); - assertThat(container.size()).isEqualTo(2 + 13); + assertThat(container.size()).isEqualTo(2 + 14); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java index a9e11305722..0bd5afff1a9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java @@ -25,7 +25,6 @@ import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.server.issue.ws.AvatarResolver; -import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.user.UserUpdater; import org.sonar.server.user.index.UserIndex; @@ -45,7 +44,6 @@ public class UsersWsTest { WsTester tester = new WsTester(new UsersWs( new CreateAction(mock(DbClient.class), mock(UserUpdater.class), userSessionRule), new UpdateAction(mock(UserUpdater.class), userSessionRule, mock(UserJsonWriter.class), mock(DbClient.class)), - new CurrentAction(userSessionRule, mock(DbClient.class), mock(DefaultOrganizationProvider.class), mock(AvatarResolver.class)), new ChangePasswordAction(mock(DbClient.class), mock(UserUpdater.class), userSessionRule), new SearchAction(userSessionRule, mock(UserIndex.class), mock(DbClient.class), mock(AvatarResolver.class)))); controller = tester.controller("api/users"); @@ -56,7 +54,7 @@ public class UsersWsTest { assertThat(controller).isNotNull(); assertThat(controller.description()).isNotEmpty(); assertThat(controller.since()).isEqualTo("3.6"); - assertThat(controller.actions()).hasSize(5); + assertThat(controller.actions()).hasSize(4); } @Test @@ -92,12 +90,4 @@ public class UsersWsTest { assertThat(action.params()).hasSize(3); } - @Test - public void define_current_action() { - WebService.Action action = controller.action("current"); - assertThat(action).isNotNull(); - assertThat(action.isPost()).isFalse(); - assertThat(action.isInternal()).isTrue(); - assertThat(action.params()).isEmpty(); - } } diff --git a/sonar-ws/src/main/protobuf/ws-users.proto b/sonar-ws/src/main/protobuf/ws-users.proto index e949f00b351..cb83cede2e7 100644 --- a/sonar-ws/src/main/protobuf/ws-users.proto +++ b/sonar-ws/src/main/protobuf/ws-users.proto @@ -119,6 +119,7 @@ message CurrentWsResponse { ORGANIZATION = 2; MY_PROJECTS = 3; MY_ISSUES = 4; + PROJECTS = 5; } message Homepage { diff --git a/tests/src/test/java/org/sonarqube/tests/user/HomepageTest.java b/tests/src/test/java/org/sonarqube/tests/user/HomepageTest.java new file mode 100644 index 00000000000..884ac565884 --- /dev/null +++ b/tests/src/test/java/org/sonarqube/tests/user/HomepageTest.java @@ -0,0 +1,93 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonarqube.tests.user; + +import com.sonar.orchestrator.Orchestrator; +import javax.annotation.Nullable; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonarqube.qa.util.Tester; +import org.sonarqube.ws.Projects.CreateWsResponse.Project; +import org.sonarqube.ws.Users; +import org.sonarqube.ws.Users.CreateWsResponse.User; +import org.sonarqube.ws.Users.CurrentWsResponse.HomepageType; +import org.sonarqube.ws.client.PostRequest; +import org.sonarqube.ws.client.projects.DeleteRequest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PROJECT; +import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PROJECTS; + +public class HomepageTest { + + @ClassRule + public static final Orchestrator orchestrator = UserSuite.ORCHESTRATOR; + + @Rule + public Tester tester = new Tester(orchestrator).disableOrganizations(); + + @Test + public void default_homepage() { + User user = tester.users().generate(); + + checkHomepage(user, PROJECTS, null); + } + + @Test + public void set_and_get_homepage() { + Project project = tester.projects().provision(); + User user = tester.users().generate(); + + setHomepage(user, "PROJECT", project.getKey()); + + checkHomepage(user, PROJECT, project); + } + + @Test + public void fallback_to_projects_when_homepage_was_set_to_a_removed_project() { + User user = tester.users().generate(); + Project project = tester.projects().provision(); + setHomepage(user, "PROJECT", project.getKey()); + checkHomepage(user, PROJECT, project); + + tester.wsClient().projects().delete(new DeleteRequest().setProject(project.getKey())); + + checkHomepage(user, PROJECTS, null); + } + + private void setHomepage(User user, String type, @Nullable String component) { + tester.as(user.getLogin()).wsClient().wsConnector().call(new PostRequest("api/users/set_homepage") + .setParam("type", type) + .setParam("component", component)) + .failIfNotSuccessful(); + } + + private void checkHomepage(User user, HomepageType type, @Nullable Project project) { + Users.CurrentWsResponse current = tester.as(user.getLogin()).wsClient().users().current(); + assertThat(current.getHomepage().getType()).isEqualTo(type); + if (project != null) { + assertThat(current.getHomepage().getComponent()).isEqualTo(project.getKey()); + } else { + assertThat(current.getHomepage().hasComponent()).isFalse(); + } + } +} diff --git a/tests/src/test/java/org/sonarqube/tests/user/UserSuite.java b/tests/src/test/java/org/sonarqube/tests/user/UserSuite.java index d6b4ddb36ed..4eb7d0138dd 100644 --- a/tests/src/test/java/org/sonarqube/tests/user/UserSuite.java +++ b/tests/src/test/java/org/sonarqube/tests/user/UserSuite.java @@ -33,6 +33,7 @@ import static util.ItUtils.xooPlugin; BaseIdentityProviderTest.class, FavoritesWsTest.class, ForceAuthenticationTest.class, + HomepageTest.class, LocalAuthenticationTest.class, MyAccountPageTest.class, NotificationsWsTest.class, -- 2.39.5