]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10423 Allow homepage feature on SonarQube
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 15 Feb 2018 09:33:33 +0000 (10:33 +0100)
committerStas Vilchik <stas.vilchik@sonarsource.com>
Fri, 2 Mar 2018 12:17:32 +0000 (13:17 +0100)
14 files changed:
server/sonar-server/src/main/java/org/sonar/server/user/ws/CurrentAction.java
server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageType.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypesImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java
server/sonar-server/src/main/java/org/sonar/server/user/ws/UsersWsModule.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/HomepageTypesImplTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/UsersWsTest.java
sonar-ws/src/main/protobuf/ws-users.proto
tests/src/test/java/org/sonarqube/tests/user/HomepageTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/user/UserSuite.java

index 588af51c919f816d41f196ce0c2a1e7274e6cb23..cb959d11605d7381aa732f15807652e8a2774d64 100644 (file)
@@ -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/HomepageType.java
deleted file mode 100644 (file)
index b2ada36..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.List;
-
-import static java.util.Arrays.stream;
-import static java.util.stream.Collectors.toList;
-
-public enum HomepageType {
-
-  PROJECT, ORGANIZATION, MY_PROJECTS, MY_ISSUES;
-
-  public static List<String> keys() {
-    return stream(values()).map(Enum::toString).collect(toList());
-  }
-}
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
new file mode 100644 (file)
index 0000000..cd811d6
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.List;
+
+public interface HomepageTypes {
+
+  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
+  }
+
+  List<Type> getTypes();
+
+  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 (file)
index 0000000..026cc0b
--- /dev/null
@@ -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<Type> ON_SONARQUBE = EnumSet.of(PROJECTS, PROJECT, ORGANIZATION);
+  private static final EnumSet<Type> ON_SONARCLOUD = EnumSet.of(PROJECT, MY_PROJECTS, MY_ISSUES, ORGANIZATION);
+
+  private final Configuration configuration;
+  private final OrganizationFlags organizationFlags;
+  private final DbClient dbClient;
+
+  private List<Type> types;
+  private Type defaultType;
+
+  public HomepageTypesImpl(Configuration configuration, OrganizationFlags organizationFlags, DbClient dbClient) {
+    this.configuration = configuration;
+    this.organizationFlags = organizationFlags;
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public List<Type> 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
+  }
+}
index d802cd6bcc3dfdbc2eec42725ee83efbf6b0b26a..4765058dc95f847a798a31845bc63edb544b60b9 100644 (file)
@@ -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:
index d1bec855ed65828804bb83467cadc99bbcaa0006..39d6c3ae5de512142b3cf8f808a3ced9d09e81bb 100644 (file)
@@ -37,6 +37,7 @@ public class UsersWsModule extends Module {
       UserPropertiesWs.class,
       UserJsonWriter.class,
       SkipOnboardingTutorialAction.class,
-      SetHomepageAction.class);
+      SetHomepageAction.class,
+      HomepageTypesImpl.class);
   }
 }
index 8d58daa38a5353748e0089c0f9d48d2ed456072a..9f83fce0273a57c69d16073b292a53ed72d00d12 100644 (file)
@@ -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 (file)
index 0000000..e6c9bf7
--- /dev/null
@@ -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);
+  }
+
+}
index aca3fd2a672e00e580dbc687a8ee5f3bcba4ed8a..d04b170d8939c96814eb8c29fb7916ea0d5be351 100644 (file)
@@ -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.<br> Requires authentication.");
     assertThat(action.responseExample()).isNull();
-    assertThat(action.handler()).isSameAs(underTest);
     assertThat(action.params()).hasSize(4);
 
     WebService.Param typeParam = action.param("type");
index 443722be3d884c0a97534d93fa1236bac029e8e6..ad4e8668dd5d7744e723d7f8c572cebf9945af1c 100644 (file)
@@ -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);
   }
 }
index a9e1130572246b4b801a6137c7b8bb0ab58c80ee..0bd5afff1a9679be7d7533b700646e9fbc9486f8 100644 (file)
@@ -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();
-  }
 }
index e949f00b35155ccec0dfa0b1831102433617176f..cb83cede2e768ede14ec8de1fde2f8964b06a9c1 100644 (file)
@@ -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 (file)
index 0000000..884ac56
--- /dev/null
@@ -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();
+    }
+  }
+}
index d6b4ddb36eda2984e948c2556b6e78a9507b2dd2..4eb7d0138dd960e85f76fd4920e4831efd6e53a1 100644 (file)
@@ -33,6 +33,7 @@ import static util.ItUtils.xooPlugin;
   BaseIdentityProviderTest.class,
   FavoritesWsTest.class,
   ForceAuthenticationTest.class,
+  HomepageTest.class,
   LocalAuthenticationTest.class,
   MyAccountPageTest.class,
   NotificationsWsTest.class,