]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10182 Add api/users/set_homepage persistence
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>
Thu, 14 Dec 2017 11:04:25 +0000 (12:04 +0100)
committerStas Vilchik <stas.vilchik@sonarsource.com>
Tue, 2 Jan 2018 09:38:10 +0000 (10:38 +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/SetHomepageAction.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/SetHomepageActionTest.java

index 65e741f1c782c0cfe5bccf6d639a1f890b66133d..71a6447d1420165843bada433af17a0f9424f39f 100644 (file)
@@ -42,14 +42,13 @@ import static com.google.common.base.Strings.emptyToNull;
 import static java.lang.String.format;
 import static java.util.Collections.singletonList;
 import static java.util.stream.Collectors.toList;
-import static org.apache.commons.lang.StringUtils.isNotBlank;
 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.Users.CurrentWsResponse.Permissions;
-import static org.sonarqube.ws.Users.CurrentWsResponse.newBuilder;
 import static org.sonarqube.ws.client.user.UsersWsParameters.ACTION_CURRENT;
 
 public class CurrentAction implements UsersWsAction {
index 1adb81b82e809137c4bcf60407e32b309efa3976..5427550e81993a45245e47bbc31071251a12e2ed 100644 (file)
  */
 package org.sonar.server.user.ws;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
+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.user.UserSession;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+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 {
 
-  private static final String PARAM_TYPE = "type";
-  private static final String PARAM_VALUE = "value";
-  private static final String ACTION = "set_homepage";
+  static final String PARAM_TYPE = "type";
+  static final String PARAM_VALUE = "value";
+  static final String ACTION = "set_homepage";
+
+  private final UserSession userSession;
+  private final DbClient dbClient;
+  private final ComponentFinder componentFinder;
 
+  public SetHomepageAction(UserSession userSession, DbClient dbClient, ComponentFinder componentFinder) {
+    this.userSession = userSession;
+    this.dbClient = dbClient;
+    this.componentFinder = componentFinder;
+  }
 
   @Override
   public void define(WebService.NewController controller) {
     WebService.NewAction action = controller.createAction(ACTION)
       .setPost(true)
-      .setDescription("Set Homepage of current user.<br> Requires authentication.")
+      .setInternal(true)
+      .setDescription("Set homepage of current user.<br> Requires authentication.")
       .setSince("7.0")
       .setHandler(this);
 
@@ -44,16 +72,60 @@ public class SetHomepageAction implements UsersWsAction {
       .setPossibleValues(HomepageTypes.keys());
 
     action.createParam(PARAM_VALUE)
-      .setDescription("Additional information to filter the page (project or organization key)")
-      .setExampleValue("my-project-key");
+      .setDescription("Additional information to identify the page (project or organization key)")
+      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
 
   }
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkLoggedIn();
+
+    String type = request.mandatoryParam(PARAM_TYPE);
+    String value = request.param(PARAM_VALUE);
+
+    checkRequest(type, value);
+
+    String login = userSession.getLogin();
+
+    try (DbSession dbSession = dbClient.openSession(false)) {
+
+      UserDto user = dbClient.userDao().selectActiveUserByLogin(dbSession, login);
+      checkState(user != null, "User login '%s' cannot be found", login);
+
+      user.setHomepageType(type);
+      user.setHomepageValue(findHomepageValue(dbSession, type, value));
+
+      dbClient.userDao().update(dbSession, user);
+      dbSession.commit();
+    }
 
-    // WIP : Not implemented yet.
     response.noContent();
+  }
+
+  @CheckForNull
+  private String findHomepageValue(DbSession dbSession, String type, String value) {
+
+    if (PROJECT.toString().equals(type)) {
+      return componentFinder.getByKey(dbSession, value).uuid();
+    }
+
+    if (ORGANIZATION.toString().equals(type)) {
+      return checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, value), "No organizationDto with key '%s'", value).getUuid();
+    }
+
+    return null;
+  }
+
+  private static void checkRequest(String type, @Nullable String value) {
+
+    if (PROJECT.toString().equals(type) || ORGANIZATION.toString().equals(type)) {
+      checkArgument(isNotBlank(value), "Type %s requires a value", type);
+    }
+
+    if (MY_PROJECTS.toString().equals(type) || MY_ISSUES.toString().equals(type)) {
+      checkArgument(isBlank(value), "Parameter value must not be provided when type is %s", type);
+    }
 
   }
 }
index c84786f4d19a5e97e1e36cba15ac11f043fc6fc1..cae8af9edcd6af1febcd84fa503b540d90644a99 100644 (file)
  */
 package org.sonar.server.user.ws;
 
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.component.TestComponentFinder;
+import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestResponse;
 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_TYPE;
+import static org.sonar.server.user.ws.SetHomepageAction.PARAM_VALUE;
+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 {
 
-  private SetHomepageAction underTest = new SetHomepageAction();
-  private WsActionTester wsTester = new WsActionTester(underTest);
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  @Rule
+  public DbTester db = DbTester.create();
+
+  @Rule
+  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);
 
   @Test
   public void verify_definition() {
-    WebService.Action action = wsTester.getDef();
+    WebService.Action action = ws.getDef();
     assertThat(action.key()).isEqualTo("set_homepage");
-    assertThat(action.isInternal()).isFalse();
+    assertThat(action.isInternal()).isTrue();
     assertThat(action.isPost()).isTrue();
     assertThat(action.since()).isEqualTo("7.0");
-    assertThat(action.description()).isEqualTo("Set Homepage of current user.<br> Requires authentication.");
+    assertThat(action.description()).isEqualTo("Set homepage of current user.<br> Requires authentication.");
     assertThat(action.responseExample()).isNull();
     assertThat(action.deprecatedKey()).isNull();
     assertThat(action.deprecatedSince()).isNull();
@@ -54,12 +84,139 @@ public class SetHomepageActionTest {
 
     WebService.Param keyParam = action.param("value");
     assertThat(keyParam.isRequired()).isFalse();
-    assertThat(keyParam.description()).isEqualTo("Additional information to filter the page (project or organization key)");
-    assertThat(keyParam.exampleValue()).isEqualTo("my-project-key");
+    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();
   }
 
 
+  @Test
+  public void set_project_homepage() {
+    OrganizationDto organization = db.organizations().insert();
+    ComponentDto project = new ComponentDbTester(db).insertComponent(newPrivateProjectDto(organization));
+
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
+
+    ws.newRequest()
+      .setMethod("POST")
+      .setParam(PARAM_TYPE, PROJECT.toString())
+      .setParam(PARAM_VALUE, project.getKey())
+      .execute();
+
+    UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin());
+    assertThat(actual).isNotNull();
+    assertThat(actual.getHomepageType()).isEqualTo(PROJECT.toString());
+    assertThat(actual.getHomepageValue()).isEqualTo(project.uuid());
+  }
+
+  @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.toString())
+      .setParam(PARAM_VALUE, organization.getKey())
+      .execute();
+
+    UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin());
+    assertThat(actual).isNotNull();
+    assertThat(actual.getHomepageType()).isEqualTo(ORGANIZATION.toString());
+    assertThat(actual.getHomepageValue()).isEqualTo(organization.getUuid());
+  }
+
+  @Test
+  public void set_my_issues_homepage() {
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
+
+    ws.newRequest()
+      .setMethod("POST")
+      .setParam(PARAM_TYPE, MY_ISSUES.toString())
+      .execute();
+
+    UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin());
+    assertThat(actual).isNotNull();
+    assertThat(actual.getHomepageType()).isEqualTo(MY_ISSUES.toString());
+    assertThat(actual.getHomepageValue()).isNullOrEmpty();
+  }
+
+  @Test
+  public void set_my_projects_homepage() {
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
+
+    ws.newRequest()
+      .setMethod("POST")
+      .setParam(PARAM_TYPE, MY_PROJECTS.toString())
+      .execute();
+
+    UserDto actual = db.getDbClient().userDao().selectByLogin(db.getSession(), user.getLogin());
+    assertThat(actual).isNotNull();
+    assertThat(actual.getHomepageType()).isEqualTo(MY_PROJECTS.toString());
+    assertThat(actual.getHomepageValue()).isNullOrEmpty();
+  }
+
+  @Test
+  public void response_has_no_content() {
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
+
+    TestResponse response = ws.newRequest()
+      .setMethod("POST")
+      .setParam(PARAM_TYPE, MY_PROJECTS.toString())
+      .execute();
+
+    assertThat(response.getStatus()).isEqualTo(SC_NO_CONTENT);
+    assertThat(response.getInput()).isEmpty();
+  }
+
+  @Test
+  public void fail_when_missing_project_id_when_requesting_project_type() {
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("Type PROJECT requires a value");
+
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
+
+    ws.newRequest()
+      .setMethod("POST")
+      .setParam(PARAM_TYPE, PROJECT.toString())
+      .setParam(PARAM_VALUE, "")
+      .execute();
+
+  }
+
+  @Test
+  public void fail_when_missing_organization_id_when_requesting_organization_type() {
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("Type ORGANIZATION requires a value");
+
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
+
+    ws.newRequest()
+      .setMethod("POST")
+      .setParam(PARAM_TYPE, ORGANIZATION.toString())
+      .setParam(PARAM_VALUE, "")
+      .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