]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10423 Replace "parameter" by "component" and "organization" in api/users WS
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 13 Feb 2018 15:13:00 +0000 (16:13 +0100)
committerStas Vilchik <stas.vilchik@sonarsource.com>
Fri, 2 Mar 2018 12:17:32 +0000 (13:17 +0100)
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 [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/user/ws/HomepageTypes.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/user/ws/SetHomepageAction.java
server/sonar-server/src/main/resources/org/sonar/server/user/ws/current-example.json
server/sonar-server/src/test/java/org/sonar/server/user/ws/CurrentActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java
sonar-ws/src/main/protobuf/ws-users.proto
tests/src/test/java/org/sonarqube/tests/user/SonarCloudHomepageTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/user/SonarCloudUserSuite.java

index f79c196fe993b86ffe409821d97fa5a78e23e21b..788d85c86d1fb1a40e4c265050835c2b7123b31f 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.server.user.ws;
 
 import java.util.Collection;
 import java.util.List;
-import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -52,6 +52,7 @@ import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.PROJECT;
 import static org.sonarqube.ws.client.user.UsersWsParameters.ACTION_CURRENT;
 
 public class CurrentAction implements UsersWsAction {
+
   private final UserSession userSession;
   private final DbClient dbClient;
   private final DefaultOrganizationProvider defaultOrganizationProvider;
@@ -69,11 +70,13 @@ public class CurrentAction implements UsersWsAction {
   public void define(NewController context) {
     context.createAction(ACTION_CURRENT)
       .setDescription("Get the details of the current authenticated user.")
-      .setHandler(this)
+      .setSince("5.2")
       .setInternal(true)
+      .setHandler(this)
       .setResponseExample(getClass().getResource("current-example.json"))
-      .setSince("5.2")
-      .setChangelog(new Change("6.5", "showOnboardingTutorial is now returned in the response"));
+      .setChangelog(
+        new Change("6.5", "showOnboardingTutorial is now returned in the response"),
+        new Change("7.1", "'parameter' is replaced by 'component' and 'organization' in the response"));
   }
 
   @Override
@@ -122,34 +125,35 @@ public class CurrentAction implements UsersWsAction {
   }
 
   private CurrentWsResponse.Homepage findHomepageFor(DbSession dbSession, UserDto user) {
-    if (user.getHomepageType() == null) {
-      return defaultHomepageOf();
+    String homepageType = user.getHomepageType();
+    if (homepageType == null) {
+      return defaultHomepage();
     }
-    String homepageParameter = getHomepageParameter(dbSession, user.getHomepageType(), user.getHomepageParameter());
     CurrentWsResponse.Homepage.Builder homepage = CurrentWsResponse.Homepage.newBuilder()
-      .setType(CurrentWsResponse.HomepageType.valueOf(user.getHomepageType()));
-    setNullable(homepageParameter, homepage::setParameter);
+      .setType(CurrentWsResponse.HomepageType.valueOf(homepageType));
+    setHomepageParameter(dbSession, homepageType, user.getHomepageParameter(), homepage);
     return homepage.build();
   }
 
-  @CheckForNull
-  private String getHomepageParameter(DbSession dbSession, String homepageType, String homepageParameter) {
+  private void setHomepageParameter(DbSession dbSession, String homepageType, @Nullable String homepageParameter, CurrentWsResponse.Homepage.Builder homepage) {
     if (PROJECT.toString().equals(homepageType)) {
-      return dbClient.componentDao().selectByUuid(dbSession, homepageParameter)
-        .transform(ComponentDto::getKey)
+      checkState(homepageParameter != null, "Homepage parameter should not be null");
+      ComponentDto component = dbClient.componentDao().selectByUuid(dbSession, homepageParameter)
         .or(() -> {
           throw new IllegalStateException(format("Unknown component '%s' for homepageParameter", homepageParameter));
         });
+      homepage.setComponent(component.getKey());
+      return;
     }
     if (ORGANIZATION.toString().equals(homepageType)) {
-      return dbClient.organizationDao().selectByUuid(dbSession, homepageParameter)
-        .map(OrganizationDto::getKey)
+      checkState(homepageParameter != null, "Homepage parameter should not be null");
+      OrganizationDto organization = dbClient.organizationDao().selectByUuid(dbSession, homepageParameter)
         .orElseThrow(() -> new IllegalStateException(format("Unknown organization '%s' for homepageParameter", homepageParameter)));
+      homepage.setOrganization(organization.getKey());
     }
-    return null;
   }
 
-  private static CurrentWsResponse.Homepage defaultHomepageOf() {
+  private static CurrentWsResponse.Homepage defaultHomepage() {
     return CurrentWsResponse.Homepage.newBuilder()
       .setType(MY_PROJECTS)
       .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
new file mode 100644 (file)
index 0000000..b2ada36
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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
deleted file mode 100644 (file)
index ee19ab5..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 HomepageTypes {
-
-  PROJECT, ORGANIZATION, MY_PROJECTS, MY_ISSUES;
-
-  public static List<String> keys() {
-    return stream(values()).map(Enum::toString).collect(toList());
-  }
-}
index ee81221bb9f8b6b2afc093b729f0eb0acd1f680c..a47dd3e9da5b80d380b685832a3353f380214830 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.user.ws;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
+import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -28,24 +29,27 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 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.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.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
-import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.MY_ISSUES;
-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;
 
 public class SetHomepageAction implements UsersWsAction {
 
-  static final String PARAM_TYPE = "type";
-  static final String PARAM_PARAMETER = "parameter";
-  static final String ACTION = "set_homepage";
+  private static final String ACTION = "set_homepage";
+
+  private static final String PARAM_TYPE = "type";
+  private static final String PARAM_ORGANIZATION = "organization";
+  private static final String PARAM_COMPONENT = "component";
 
   private final UserSession userSession;
   private final DbClient dbClient;
@@ -62,40 +66,44 @@ public class SetHomepageAction implements UsersWsAction {
     WebService.NewAction action = controller.createAction(ACTION)
       .setPost(true)
       .setInternal(true)
-      .setDescription("Set homepage of current user.<br> Requires authentication.")
+      .setDescription("Set homepage of current user.<br> " +
+        "Requires authentication.")
       .setSince("7.0")
+      .setChangelog(new Change("7.1", "Parameter 'parameter' is replaced by 'component' and 'organization'"))
       .setHandler(this);
 
     action.createParam(PARAM_TYPE)
       .setDescription("Type of the requested page")
       .setRequired(true)
-      .setPossibleValues(HomepageTypes.keys());
+      .setPossibleValues(keys());
 
-    action.createParam(PARAM_PARAMETER)
-      .setDescription("Additional information to identify the page (project or organization key)")
-      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
+    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")
+      .setInternal(false)
+      .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)
+      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
   }
 
   @Override
   public void handle(Request request, Response response) throws Exception {
     userSession.checkLoggedIn();
-
-    String type = request.mandatoryParam(PARAM_TYPE);
-    String parameter = request.param(PARAM_PARAMETER);
-
-    checkRequest(type, parameter);
-
-    String login = userSession.getLogin();
+    HomepageType type = valueOf(request.mandatoryParam(PARAM_TYPE));
+    String componentParameter = request.param(PARAM_COMPONENT);
+    String organizationParameter = request.param(PARAM_ORGANIZATION);
 
     try (DbSession dbSession = dbClient.openSession(false)) {
+      String parameter = getHomepageParameter(dbSession, type, componentParameter, organizationParameter);
 
-      UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, login);
-      checkState(user != null, "User login '%s' cannot be found", login);
-
-      user.setHomepageType(type);
-      user.setHomepageParameter(findHomepageParameter(dbSession, type, parameter));
+      UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, userSession.getLogin());
+      checkState(user != null, "User login '%s' cannot be found", userSession.getLogin());
 
+      user.setHomepageType(type.name());
+      user.setHomepageParameter(parameter);
       dbClient.userDao().update(dbSession, user);
       dbSession.commit();
     }
@@ -104,28 +112,24 @@ public class SetHomepageAction implements UsersWsAction {
   }
 
   @CheckForNull
-  private String findHomepageParameter(DbSession dbSession, String type, String parameter) {
-
-    if (PROJECT.toString().equals(type)) {
-      return componentFinder.getByKey(dbSession, parameter).uuid();
+  private String getHomepageParameter(DbSession dbSession, HomepageType type, @Nullable String componentParameter, @Nullable String organizationParameter) {
+    switch (type) {
+      case PROJECT:
+        checkArgument(isNotBlank(componentParameter), "Type %s requires a parameter '%s'", type.name(), PARAM_COMPONENT);
+        return componentFinder.getByKey(dbSession, componentParameter).uuid();
+      case ORGANIZATION:
+        checkArgument(isNotBlank(organizationParameter), "Type %s requires a parameter '%s'", type.name(), PARAM_ORGANIZATION);
+        return dbClient.organizationDao().selectByKey(dbSession, organizationParameter)
+          .orElseThrow(() -> new NotFoundException(format("No organizationDto with key '%s'", organizationParameter)))
+          .getUuid();
+      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()));
     }
-
-    if (ORGANIZATION.toString().equals(type)) {
-      return checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, parameter), "No organizationDto with key '%s'", parameter).getUuid();
-    }
-
-    return null;
   }
 
-  private static void checkRequest(String type, @Nullable String parameter) {
-
-    if (PROJECT.toString().equals(type) || ORGANIZATION.toString().equals(type)) {
-      checkArgument(isNotBlank(parameter), "Type %s requires a parameter", type);
-    }
-
-    if (MY_PROJECTS.toString().equals(type) || MY_ISSUES.toString().equals(type)) {
-      checkArgument(isBlank(parameter), "Parameter parameter must not be provided when type is %s", type);
-    }
-
-  }
 }
index 66629ea66f685c92e5fe8155f6f8a61e57d123a7..7bd1e6b84e06a3fd77f435c1185e52c954db9f2d 100644 (file)
@@ -15,6 +15,6 @@
   },
   "homepage": {
     "type": "PROJECT",
-    "parameter": "death-star-key"
+    "component": "death-star-key"
   }
 }
index dd909a3df112b0a82fecb7d4d43409d368812841..ad90b5f84436f172627f07977d40deabef3beecf 100644 (file)
@@ -216,7 +216,7 @@ public class CurrentActionTest {
     assertThat(definition.isInternal()).isTrue();
     assertThat(definition.responseExampleAsString()).isNotEmpty();
     assertThat(definition.params()).isEmpty();
-    assertThat(definition.changelog()).hasSize(1);
+    assertThat(definition.changelog()).hasSize(2);
   }
 
   private CurrentWsResponse call() {
@@ -245,5 +245,4 @@ public class CurrentActionTest {
     call();
   }
 
-
 }
index 8da5af9f67b915280617803bdbcd84bada8da6e2..5c649cd27d5be6a9e3c1cfa943f5ab1054f7311d 100644 (file)
@@ -38,12 +38,6 @@ import org.sonar.server.ws.WsActionTester;
 import static org.apache.http.HttpStatus.SC_NO_CONTENT;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
-import static org.sonar.server.user.ws.SetHomepageAction.PARAM_PARAMETER;
-import static org.sonar.server.user.ws.SetHomepageAction.PARAM_TYPE;
-import static org.sonarqube.ws.Users.CurrentWsResponse.HomepageType.MY_ISSUES;
-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;
 
 public class SetHomepageActionTest {
 
@@ -69,28 +63,24 @@ 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.deprecatedKey()).isNull();
-    assertThat(action.deprecatedSince()).isNull();
     assertThat(action.handler()).isSameAs(underTest);
-    assertThat(action.params()).hasSize(2);
+    assertThat(action.params()).hasSize(3);
 
     WebService.Param typeParam = action.param("type");
     assertThat(typeParam.isRequired()).isTrue();
     assertThat(typeParam.description()).isEqualTo("Type of the requested page");
-    assertThat(typeParam.defaultValue()).isNull();
     assertThat(typeParam.possibleValues()).containsExactlyInAnyOrder("PROJECT", "ORGANIZATION", "MY_PROJECTS", "MY_ISSUES");
-    assertThat(typeParam.deprecatedSince()).isNull();
-    assertThat(typeParam.deprecatedKey()).isNull();
-
-    WebService.Param keyParam = action.param("parameter");
-    assertThat(keyParam.isRequired()).isFalse();
-    assertThat(keyParam.description()).isEqualTo("Additional information to identify the page (project or organization key)");
-    assertThat(keyParam.exampleValue()).isEqualTo("my_project");
-    assertThat(keyParam.defaultValue()).isNull();
-    assertThat(keyParam.deprecatedSince()).isNull();
-    assertThat(keyParam.deprecatedKey()).isNull();
-  }
 
+    WebService.Param componentParam = action.param("component");
+    assertThat(componentParam.isRequired()).isFalse();
+    assertThat(componentParam.description()).isEqualTo("Project key. It should only be used when parameter 'type' is set to 'PROJECT'");
+    assertThat(componentParam.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
   public void set_project_homepage() {
@@ -102,13 +92,13 @@ public class SetHomepageActionTest {
 
     ws.newRequest()
       .setMethod("POST")
-      .setParam(PARAM_TYPE, PROJECT.toString())
-      .setParam(PARAM_PARAMETER, project.getKey())
+      .setParam("type", "PROJECT")
+      .setParam("component", project.getKey())
       .execute();
 
     UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin());
     assertThat(actual).isNotNull();
-    assertThat(actual.getHomepageType()).isEqualTo(PROJECT.toString());
+    assertThat(actual.getHomepageType()).isEqualTo("PROJECT");
     assertThat(actual.getHomepageParameter()).isEqualTo(project.uuid());
   }
 
@@ -121,13 +111,13 @@ public class SetHomepageActionTest {
 
     ws.newRequest()
       .setMethod("POST")
-      .setParam(PARAM_TYPE, ORGANIZATION.toString())
-      .setParam(PARAM_PARAMETER, organization.getKey())
+      .setParam("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.toString());
+    assertThat(actual.getHomepageType()).isEqualTo("ORGANIZATION");
     assertThat(actual.getHomepageParameter()).isEqualTo(organization.getUuid());
   }
 
@@ -138,12 +128,12 @@ public class SetHomepageActionTest {
 
     ws.newRequest()
       .setMethod("POST")
-      .setParam(PARAM_TYPE, MY_ISSUES.toString())
+      .setParam("type", "MY_ISSUES")
       .execute();
 
     UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin());
     assertThat(actual).isNotNull();
-    assertThat(actual.getHomepageType()).isEqualTo(MY_ISSUES.toString());
+    assertThat(actual.getHomepageType()).isEqualTo("MY_ISSUES");
     assertThat(actual.getHomepageParameter()).isNullOrEmpty();
   }
 
@@ -154,12 +144,12 @@ public class SetHomepageActionTest {
 
     ws.newRequest()
       .setMethod("POST")
-      .setParam(PARAM_TYPE, MY_PROJECTS.toString())
+      .setParam("type", "MY_PROJECTS")
       .execute();
 
     UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin());
     assertThat(actual).isNotNull();
-    assertThat(actual.getHomepageType()).isEqualTo(MY_PROJECTS.toString());
+    assertThat(actual.getHomepageType()).isEqualTo("MY_PROJECTS");
     assertThat(actual.getHomepageParameter()).isNullOrEmpty();
   }
 
@@ -170,7 +160,7 @@ public class SetHomepageActionTest {
 
     TestResponse response = ws.newRequest()
       .setMethod("POST")
-      .setParam(PARAM_TYPE, MY_PROJECTS.toString())
+      .setParam("type", "MY_PROJECTS")
       .execute();
 
     assertThat(response.getStatus()).isEqualTo(SC_NO_CONTENT);
@@ -178,45 +168,41 @@ public class SetHomepageActionTest {
   }
 
   @Test
-  public void fail_when_missing_project_id_when_requesting_project_type() {
+  public void fail_when_missing_project_key_when_requesting_project_type() {
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("Type PROJECT requires a parameter");
 
-    UserDto user = db.users().insertUser();
-    userSession.logIn(user);
-
     ws.newRequest()
       .setMethod("POST")
-      .setParam(PARAM_TYPE, PROJECT.toString())
-      .setParam(PARAM_PARAMETER, "")
+      .setParam("type", "PROJECT")
       .execute();
 
   }
 
   @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");
 
-    UserDto user = db.users().insertUser();
-    userSession.logIn(user);
-
     ws.newRequest()
       .setMethod("POST")
-      .setParam(PARAM_TYPE, ORGANIZATION.toString())
-      .setParam(PARAM_PARAMETER, "")
+      .setParam("type", "ORGANIZATION")
       .execute();
-
   }
 
   @Test
   public void fail_for_anonymous() {
     userSession.anonymous();
+
     expectedException.expect(UnauthorizedException.class);
     expectedException.expectMessage("Authentication is required");
 
     ws.newRequest().setMethod("POST").execute();
   }
-}
\ No newline at end of file
+}
index bcb9e798111b126af8e7f6117bf79e26c4db6dc4..35243f08a2ff37c31d65693c4236a7417c663bc0 100644 (file)
@@ -123,6 +123,7 @@ message CurrentWsResponse {
 
   message Homepage {
     optional HomepageType type = 1;
-    optional string parameter = 2;
+    optional string component = 2;
+    optional string organization = 3;
   }
 }
diff --git a/tests/src/test/java/org/sonarqube/tests/user/SonarCloudHomepageTest.java b/tests/src/test/java/org/sonarqube/tests/user/SonarCloudHomepageTest.java
new file mode 100644 (file)
index 0000000..140999b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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.Organizations.Organization;
+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.MY_ISSUES;
+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;
+
+public class SonarCloudHomepageTest {
+
+  @ClassRule
+  public static final Orchestrator orchestrator = SonarCloudUserSuite.ORCHESTRATOR;
+
+  @Rule
+  public Tester tester = new Tester(orchestrator);
+
+  @Test
+  public void default_homepage() {
+    Organization organization = tester.organizations().generate();
+    User user = tester.users().generateMember(organization);
+
+    checkHomepage(user, MY_PROJECTS, null, null);
+  }
+
+  @Test
+  public void set_and_get_homepage() {
+    Organization organization = tester.organizations().generate();
+    User user = tester.users().generateMember(organization);
+
+    setHomepage(user, "MY_ISSUES", null, null);
+
+    checkHomepage(user, MY_ISSUES, null, null);
+  }
+
+  @Test
+  public void fallback_to_my_projects_when_homepage_was_set_to_a_removed_project() {
+    Organization organization = tester.organizations().generate();
+    User user = tester.users().generateMember(organization);
+    Project project = tester.projects().provision(organization);
+    setHomepage(user, "PROJECT", null, project.getKey());
+    checkHomepage(user, PROJECT, null, project);
+
+    tester.wsClient().projects().delete(new DeleteRequest().setProject(project.getKey()));
+
+    checkHomepage(user, MY_PROJECTS, null, null);
+  }
+
+  @Test
+  public void fallback_to_my_projects_when_homepage_was_set_to_a_removed_organization() {
+    Organization organization = tester.organizations().generate();
+    User user = tester.users().generateMember(organization);
+    setHomepage(user, "ORGANIZATION", organization.getKey(), null);
+    checkHomepage(user, ORGANIZATION, organization, null);
+
+    tester.wsClient().organizations().delete(new org.sonarqube.ws.client.organizations.DeleteRequest().setOrganization(organization.getKey()));
+
+    checkHomepage(user, MY_PROJECTS, null, null);
+  }
+
+  private void setHomepage(User user, String type, @Nullable String organization, @Nullable String component) {
+    // Do not call the java user client as it's only generated for SonarQube, not for SonarCloud
+    tester.as(user.getLogin()).wsClient().wsConnector().call(new PostRequest("api/users/set_homepage")
+      .setParam("type", type)
+      .setParam("organization", organization)
+      .setParam("component", component))
+      .failIfNotSuccessful();
+  }
+
+  private void checkHomepage(User user, HomepageType type, @Nullable Organization organization, @Nullable Project project) {
+    Users.CurrentWsResponse current = tester.as(user.getLogin()).wsClient().users().current();
+    assertThat(current.getHomepage().getType()).isEqualTo(type);
+    if (organization != null) {
+      assertThat(current.getHomepage().getOrganization()).isEqualTo(organization.getKey());
+    } else {
+      assertThat(current.getHomepage().hasOrganization()).isFalse();
+    }
+    if (project != null) {
+      assertThat(current.getHomepage().getComponent()).isEqualTo(project.getKey());
+    } else {
+      assertThat(current.getHomepage().hasComponent()).isFalse();
+    }
+  }
+}
index b14ad6da627dff59f3df349c58d37f735779dcdf..afc1db9614577d11bdafe53323b99bcf91e7a522 100644 (file)
@@ -29,6 +29,7 @@ import static util.ItUtils.xooPlugin;
 
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
+  SonarCloudHomepageTest.class,
   SonarCloudNotificationsWsTest.class
 })
 public class SonarCloudUserSuite {