You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UpdateActionTest.java 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.user.ws;
  21. import java.util.Arrays;
  22. import org.junit.Before;
  23. import org.junit.Rule;
  24. import org.junit.Test;
  25. import org.junit.rules.ExpectedException;
  26. import org.sonar.api.config.internal.MapSettings;
  27. import org.sonar.api.utils.System2;
  28. import org.sonar.db.DbClient;
  29. import org.sonar.db.DbSession;
  30. import org.sonar.db.DbTester;
  31. import org.sonar.db.user.UserDto;
  32. import org.sonar.server.authentication.CredentialsLocalAuthentication;
  33. import org.sonar.server.es.EsTester;
  34. import org.sonar.server.exceptions.ForbiddenException;
  35. import org.sonar.server.exceptions.NotFoundException;
  36. import org.sonar.server.organization.DefaultOrganizationProvider;
  37. import org.sonar.server.organization.OrganizationUpdater;
  38. import org.sonar.server.organization.TestDefaultOrganizationProvider;
  39. import org.sonar.server.organization.TestOrganizationFlags;
  40. import org.sonar.server.tester.UserSessionRule;
  41. import org.sonar.server.user.NewUserNotifier;
  42. import org.sonar.server.user.UserUpdater;
  43. import org.sonar.server.user.index.UserIndexer;
  44. import org.sonar.server.usergroups.DefaultGroupFinder;
  45. import org.sonar.server.ws.WsActionTester;
  46. import static com.google.common.collect.Lists.newArrayList;
  47. import static java.util.Collections.singletonList;
  48. import static org.assertj.core.api.Assertions.assertThat;
  49. import static org.mockito.Mockito.mock;
  50. import static org.sonar.db.user.UserTesting.newUserDto;
  51. public class UpdateActionTest {
  52. private static final OrganizationUpdater ORGANIZATION_CREATION_NOT_USED_FOR_UPDATE = null;
  53. private MapSettings settings = new MapSettings();
  54. private System2 system2 = new System2();
  55. @Rule
  56. public DbTester db = DbTester.create(system2);
  57. @Rule
  58. public EsTester es = EsTester.create();
  59. @Rule
  60. public UserSessionRule userSession = UserSessionRule.standalone().logIn().setSystemAdministrator();
  61. @Rule
  62. public ExpectedException expectedException = ExpectedException.none();
  63. private DbClient dbClient = db.getDbClient();
  64. private DbSession dbSession = db.getSession();
  65. private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
  66. private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
  67. private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
  68. private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient());
  69. private WsActionTester ws = new WsActionTester(new UpdateAction(
  70. new UserUpdater(system2, mock(NewUserNotifier.class), dbClient, userIndexer, organizationFlags, defaultOrganizationProvider, ORGANIZATION_CREATION_NOT_USED_FOR_UPDATE,
  71. new DefaultGroupFinder(db.getDbClient()), settings.asConfig(), localAuthentication),
  72. userSession, new UserJsonWriter(userSession), dbClient));
  73. @Before
  74. public void setUp() {
  75. db.users().insertDefaultGroup(db.getDefaultOrganization(), "sonar-users");
  76. }
  77. @Test
  78. public void update_user() {
  79. createUser();
  80. ws.newRequest()
  81. .setParam("login", "john")
  82. .setParam("name", "Jon Snow")
  83. .setParam("email", "jon.snow@thegreatw.all")
  84. .setParam("scmAccounts", "jon.snow")
  85. .execute()
  86. .assertJson(getClass(), "update_user.json");
  87. }
  88. @Test
  89. public void update_only_name() {
  90. createUser();
  91. ws.newRequest()
  92. .setParam("login", "john")
  93. .setParam("name", "Jon Snow")
  94. .execute()
  95. .assertJson(getClass(), "update_name.json");
  96. }
  97. @Test
  98. public void update_only_email() {
  99. createUser();
  100. ws.newRequest()
  101. .setParam("login", "john")
  102. .setParam("email", "jon.snow@thegreatw.all")
  103. .execute()
  104. .assertJson(getClass(), "update_email.json");
  105. }
  106. @Test
  107. public void blank_email_is_updated_to_null() {
  108. createUser();
  109. ws.newRequest()
  110. .setParam("login", "john")
  111. .setParam("email", "")
  112. .execute()
  113. .assertJson(getClass(), "blank_email_is_updated_to_null.json");
  114. UserDto userDto = dbClient.userDao().selectByLogin(dbSession, "john");
  115. assertThat(userDto.getEmail()).isNull();
  116. }
  117. @Test
  118. public void remove_scm_accounts() {
  119. createUser();
  120. ws.newRequest()
  121. .setParam("login", "john")
  122. .setMultiParam("scmAccount", singletonList(""))
  123. .execute();
  124. UserDto userDto = dbClient.userDao().selectByLogin(dbSession, "john");
  125. assertThat(userDto.getScmAccounts()).isNull();
  126. }
  127. @Test
  128. public void update_only_scm_accounts() {
  129. createUser();
  130. ws.newRequest()
  131. .setParam("login", "john")
  132. .setMultiParam("scmAccount", singletonList("jon.snow"))
  133. .execute()
  134. .assertJson(getClass(), "update_scm_accounts.json");
  135. UserDto user = dbClient.userDao().selectByLogin(dbSession, "john");
  136. assertThat(user.getScmAccountsAsList()).containsOnly("jon.snow");
  137. }
  138. @Test
  139. public void update_scm_account_having_coma() {
  140. createUser();
  141. ws.newRequest()
  142. .setParam("login", "john")
  143. .setMultiParam("scmAccount", singletonList("jon,snow"))
  144. .execute();
  145. UserDto user = dbClient.userDao().selectByLogin(dbSession, "john");
  146. assertThat(user.getScmAccountsAsList()).containsOnly("jon,snow");
  147. }
  148. @Test
  149. public void update_scm_account_ignores_duplicates() {
  150. createUser();
  151. ws.newRequest()
  152. .setParam("login", "john")
  153. .setMultiParam("scmAccount", Arrays.asList("jon.snow", "jon.snow", "jon.jon", "jon.snow"))
  154. .execute();
  155. UserDto user = dbClient.userDao().selectByLogin(dbSession, "john");
  156. assertThat(user.getScmAccountsAsList()).containsExactlyInAnyOrder("jon.jon", "jon.snow");
  157. }
  158. @Test
  159. public void update_scm_account_ordered_case_insensitive() {
  160. createUser();
  161. ws.newRequest()
  162. .setParam("login", "john")
  163. .setMultiParam("scmAccount", Arrays.asList("jon.3", "Jon.1", "JON.2"))
  164. .execute();
  165. UserDto user = dbClient.userDao().selectByLogin(dbSession, "john");
  166. assertThat(user.getScmAccountsAsList()).containsExactly("Jon.1", "JON.2", "jon.3");
  167. }
  168. @Test
  169. public void update_only_scm_accounts_with_deprecated_scmAccounts_parameter() {
  170. createUser();
  171. ws.newRequest()
  172. .setParam("login", "john")
  173. .setParam("scmAccounts", "jon.snow")
  174. .execute()
  175. .assertJson(getClass(), "update_scm_accounts.json");
  176. UserDto user = dbClient.userDao().selectByLogin(dbSession, "john");
  177. assertThat(user.getScmAccountsAsList()).containsOnly("jon.snow");
  178. }
  179. @Test
  180. public void update_only_scm_accounts_with_deprecated_scm_accounts_parameter() {
  181. createUser();
  182. ws.newRequest()
  183. .setParam("login", "john")
  184. .setParam("scm_accounts", "jon.snow")
  185. .execute()
  186. .assertJson(getClass(), "update_scm_accounts.json");
  187. UserDto user = dbClient.userDao().selectByLogin(dbSession, "john");
  188. assertThat(user.getScmAccountsAsList()).containsOnly("jon.snow");
  189. }
  190. @Test
  191. public void fail_on_missing_permission() {
  192. createUser();
  193. userSession.logIn("polop");
  194. expectedException.expect(ForbiddenException.class);
  195. ws.newRequest()
  196. .setParam("login", "john")
  197. .execute();
  198. }
  199. @Test
  200. public void fail_on_unknown_user() {
  201. expectedException.expect(NotFoundException.class);
  202. expectedException.expectMessage("User 'john' doesn't exist");
  203. ws.newRequest()
  204. .setParam("login", "john")
  205. .execute();
  206. }
  207. @Test
  208. public void fail_on_disabled_user() {
  209. db.users().insertUser(u -> u.setLogin("john").setActive(false));
  210. expectedException.expect(NotFoundException.class);
  211. expectedException.expectMessage("User 'john' doesn't exist");
  212. ws.newRequest()
  213. .setParam("login", "john")
  214. .execute();
  215. }
  216. @Test
  217. public void fail_on_invalid_email() {
  218. createUser();
  219. expectedException.expect(IllegalArgumentException.class);
  220. expectedException.expectMessage("Email 'invalid-email' is not valid");
  221. ws.newRequest()
  222. .setParam("login", "john")
  223. .setParam("email", "invalid-email")
  224. .execute();
  225. }
  226. private void createUser() {
  227. UserDto userDto = newUserDto()
  228. .setEmail("john@email.com")
  229. .setLogin("john")
  230. .setName("John")
  231. .setScmAccounts(newArrayList("jn"))
  232. .setActive(true)
  233. .setLocal(true)
  234. .setExternalLogin("jo")
  235. .setExternalIdentityProvider("sonarqube");
  236. dbClient.userDao().insert(dbSession, userDto);
  237. userIndexer.commitAndIndex(dbSession, userDto);
  238. }
  239. }