aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-06-12 11:16:11 +0200
committerStas Vilchik <stas.vilchik@sonarsource.com>2017-06-20 04:10:53 -0700
commitcfe397774d465f2cf06a799f2223d3e250284d54 (patch)
treefb5356269557d4f78e3aa9779cf6735b2f01cf5a
parentcd6b35e42839c7992c520e1dd78d50edff268fde (diff)
downloadsonarqube-cfe397774d465f2cf06a799f2223d3e250284d54.tar.gz
sonarqube-cfe397774d465f2cf06a799f2223d3e250284d54.zip
SONAR-9356 skipOnboardingTutorial updates user flag
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/ws/SkipOnboardingTutorialAction.java36
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/user/ws/SkipOnboardingTutorialActionTest.java102
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/user/UsersWsParameters.java2
4 files changed, 129 insertions, 12 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java
index f45573f7dc5..ecc767b006f 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java
@@ -45,6 +45,7 @@ public class UserDao implements Dao {
this.system2 = system2;
}
+ @CheckForNull
public UserDto selectUserById(DbSession session, int userId) {
return mapper(session).selectUser(userId);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/SkipOnboardingTutorialAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/SkipOnboardingTutorialAction.java
index 39359a9f153..003208121d2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/SkipOnboardingTutorialAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/SkipOnboardingTutorialAction.java
@@ -22,22 +22,52 @@ package org.sonar.server.user.ws;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.user.UserSession;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.sonarqube.ws.client.user.UsersWsParameters.ACTION_SKIP_ONBOARDING_TUTORIAL;
public class SkipOnboardingTutorialAction implements UsersWsAction {
+ private final UserSession userSession;
+ private final DbClient dbClient;
+ private final System2 system2;
+
+ public SkipOnboardingTutorialAction(UserSession userSession, DbClient dbClient, System2 system2) {
+ this.userSession = userSession;
+ this.dbClient = dbClient;
+ this.system2 = system2;
+ }
+
@Override
public void define(WebService.NewController context) {
- context.createAction("skipOnboardingTutorial")
+ context.createAction(ACTION_SKIP_ONBOARDING_TUTORIAL)
.setPost(true)
.setInternal(true)
- .setDescription("Stores that the user has skipped the onboarding tutorial and does not want to see it after future logins." +
- " Calling this webservice several times will silently ignore subsequent requests.")
+ .setDescription("Stores that the user has skipped the onboarding tutorial and does not want to see it after future logins.<br/>" +
+ "Requires authentication.")
.setSince("6.5")
.setHandler(this);
}
@Override
public void handle(Request request, Response response) throws Exception {
+ userSession.checkLoggedIn();
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ String userLogin = userSession.getLogin();
+ UserDto userDto = dbClient.userDao().selectActiveUserByLogin(dbSession, userLogin);
+ checkState(userDto != null, "User login '%s' cannot be found", userLogin);
+ if (!userDto.isOnboarded()) {
+ userDto.setOnboarded(true);
+ userDto.setUpdatedAt(system2.now());
+ dbClient.userDao().update(dbSession, userDto);
+ dbSession.commit();
+ }
+ }
response.noContent();
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SkipOnboardingTutorialActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SkipOnboardingTutorialActionTest.java
index 85985b76ec0..df97cd664de 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/user/ws/SkipOnboardingTutorialActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/user/ws/SkipOnboardingTutorialActionTest.java
@@ -19,8 +19,15 @@
*/
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.api.utils.internal.TestSystem2;
+import org.sonar.db.DbTester;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
@@ -28,21 +35,100 @@ import static org.assertj.core.api.Assertions.assertThat;
public class SkipOnboardingTutorialActionTest {
+ private final static long PAST = 100_000_000_000L;
+ private final static long NOW = 500_000_000_000L;
+
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ @Rule
+ public DbTester db = DbTester.create();
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private TestSystem2 system2 = new TestSystem2().setNow(NOW);
+
+ private WsActionTester ws = new WsActionTester(new SkipOnboardingTutorialAction(userSession, db.getDbClient(), system2));
+
+ @Test
+ public void mark_user_as_onboarded() {
+ UserDto user = db.users().insertUser(u -> u
+ .setOnboarded(false)
+ .setUpdatedAt(PAST));
+ userSession.logIn(user);
+
+ call();
+
+ UserDto userDto = selectUser(user.getLogin());
+ assertThat(userDto.isOnboarded()).isEqualTo(true);
+ assertThat(userDto.getUpdatedAt()).isEqualTo(NOW);
+ }
+
+ @Test
+ public void does_nothing_if_user_already_onboarded() {
+ UserDto user = db.users().insertUser(u -> u
+ .setOnboarded(true)
+ .setUpdatedAt(PAST));
+ userSession.logIn(user);
+
+ call();
+
+ UserDto userDto = selectUser(user.getLogin());
+ assertThat(userDto.isOnboarded()).isEqualTo(true);
+ assertThat(userDto.getUpdatedAt()).isEqualTo(PAST);
+ }
+
+ @Test
+ public void fail_for_anonymous() {
+ userSession.anonymous();
+ expectedException.expect(UnauthorizedException.class);
+ expectedException.expectMessage("Authentication is required");
+
+ call();
+ }
+
+ @Test
+ public void fail_with_ISE_when_user_login_in_db_does_not_exist() {
+ db.users().insertUser(usert -> usert.setLogin("another"));
+ userSession.logIn("obiwan.kenobi");
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("User login 'obiwan.kenobi' cannot be found");
+
+ call();
+ }
+
@Test
- public void should_have_a_good_definition() {
- WsActionTester ws = new WsActionTester(new SkipOnboardingTutorialAction());
+ public void response_has_no_content() {
+ UserDto user = db.users().insertUser(u -> u.setOnboarded(false));
+ userSession.logIn(user);
+
+ TestResponse response = call();
+
+ assertThat(response.getStatus()).isEqualTo(204);
+ assertThat(response.getInput()).isEmpty();
+ }
+
+ @Test
+ public void test_definition() {
+ WsActionTester ws = new WsActionTester(new SkipOnboardingTutorialAction(userSession, db.getDbClient(), system2));
WebService.Action def = ws.getDef();
assertThat(def.isPost()).isTrue();
assertThat(def.isInternal()).isTrue();
assertThat(def.since()).isEqualTo("6.5");
assertThat(def.params()).isEmpty();
+ assertThat(def.changelog()).isEmpty();
}
- @Test
- public void should_return_silently() {
- WsActionTester ws = new WsActionTester(new SkipOnboardingTutorialAction());
- TestResponse response = ws.newRequest().setMethod("POST").execute();
- assertThat(response.getStatus()).isEqualTo(204);
- assertThat(response.getInput()).isEmpty();
+ private TestResponse call() {
+ return ws.newRequest().setMethod("POST").execute();
+ }
+
+ private UserDto selectUser(String userLogin) {
+ UserDto userDto = db.getDbClient().userDao().selectByLogin(db.getSession(), userLogin);
+ assertThat(userDto).isNotNull();
+ return userDto;
}
+
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/user/UsersWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/user/UsersWsParameters.java
index c79994c1a40..6ffecd751b0 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/user/UsersWsParameters.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/user/UsersWsParameters.java
@@ -27,7 +27,7 @@ public class UsersWsParameters {
public static final String ACTION_CREATE = "create";
public static final String ACTION_UPDATE = "update";
public static final String ACTION_GROUPS = "groups";
- public static final String ACTION_SKIP_ONBOARDING_TUTORIAL = "skipOnboardingTutorial";
+ public static final String ACTION_SKIP_ONBOARDING_TUTORIAL = "skip_onboarding_tutorial";
public static final String PARAM_ORGANIZATION = "organization";
public static final String PARAM_LOGIN = "login";