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.

SetBaselineActionTest.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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.projectanalysis.ws;
  21. import com.google.common.collect.ImmutableMap;
  22. import com.tngtech.java.junit.dataprovider.DataProvider;
  23. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  24. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  25. import java.util.Collections;
  26. import java.util.HashMap;
  27. import java.util.Map;
  28. import javax.annotation.Nullable;
  29. import org.junit.Rule;
  30. import org.junit.Test;
  31. import org.junit.rules.ExpectedException;
  32. import org.junit.runner.RunWith;
  33. import org.sonar.api.server.ws.WebService;
  34. import org.sonar.api.utils.System2;
  35. import org.sonar.api.web.UserRole;
  36. import org.sonar.db.DbClient;
  37. import org.sonar.db.DbSession;
  38. import org.sonar.db.DbTester;
  39. import org.sonar.db.component.BranchDto;
  40. import org.sonar.db.component.BranchType;
  41. import org.sonar.db.component.ComponentDto;
  42. import org.sonar.db.component.ComponentTesting;
  43. import org.sonar.db.component.SnapshotDto;
  44. import org.sonar.server.component.TestComponentFinder;
  45. import org.sonar.server.exceptions.ForbiddenException;
  46. import org.sonar.server.exceptions.NotFoundException;
  47. import org.sonar.server.tester.UserSessionRule;
  48. import org.sonar.server.ws.TestRequest;
  49. import org.sonar.server.ws.WsActionTester;
  50. import static org.assertj.core.api.Assertions.assertThat;
  51. import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_ANALYSIS;
  52. import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_BRANCH;
  53. import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_PROJECT;
  54. import static org.sonar.test.Matchers.regexMatcher;
  55. import static org.sonarqube.ws.client.WsRequest.Method.POST;
  56. @RunWith(DataProviderRunner.class)
  57. public class SetBaselineActionTest {
  58. @Rule
  59. public ExpectedException expectedException = ExpectedException.none();
  60. @Rule
  61. public UserSessionRule userSession = UserSessionRule.standalone();
  62. @Rule
  63. public DbTester db = DbTester.create(System2.INSTANCE);
  64. private DbClient dbClient = db.getDbClient();
  65. private DbSession dbSession = db.getSession();
  66. private WsActionTester ws = new WsActionTester(new SetBaselineAction(dbClient, userSession, TestComponentFinder.from(db)));
  67. @Test
  68. @UseDataProvider("nullOrEmpty")
  69. public void set_baseline_on_main_branch(@Nullable String branchName) {
  70. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  71. BranchDto branch = new BranchDto()
  72. .setBranchType(BranchType.LONG)
  73. .setProjectUuid(project.uuid())
  74. .setUuid(project.uuid())
  75. .setKey("master");
  76. db.components().insertComponent(project);
  77. db.getDbClient().branchDao().insert(dbSession, branch);
  78. SnapshotDto analysis = db.components().insertSnapshot(project);
  79. logInAsProjectAdministrator(project);
  80. call(project.getKey(), branchName, analysis.getUuid());
  81. BranchDto loaded = dbClient.branchDao().selectByUuid(dbSession, branch.getUuid()).get();
  82. assertThat(loaded.getManualBaseline()).isEqualTo(analysis.getUuid());
  83. }
  84. @DataProvider
  85. public static Object[][] nullOrEmpty() {
  86. return new Object[][] {
  87. {null},
  88. {""},
  89. {" "},
  90. };
  91. }
  92. @Test
  93. public void set_baseline_on_long_living_branch() {
  94. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  95. BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
  96. db.components().insertProjectBranch(project, branch);
  97. ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
  98. SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
  99. logInAsProjectAdministrator(project);
  100. call(project.getKey(), branch.getKey(), analysis.getUuid());
  101. BranchDto loaded = dbClient.branchDao().selectByUuid(dbSession, branch.getUuid()).get();
  102. assertThat(loaded.getManualBaseline()).isEqualTo(analysis.getUuid());
  103. }
  104. @Test
  105. public void fail_when_user_is_not_admin() {
  106. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  107. BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
  108. db.components().insertProjectBranch(project, branch);
  109. ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
  110. SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
  111. expectedException.expect(ForbiddenException.class);
  112. expectedException.expectMessage("Insufficient privileges");
  113. call(project.getKey(), branch.getKey(), analysis.getUuid());
  114. }
  115. @Test
  116. @UseDataProvider("missingOrEmptyParamsAndFailureMessage")
  117. public void fail_with_IAE_when_required_param_missing_or_empty(Map<String, String> params, String message) {
  118. expectedException.expect(IllegalArgumentException.class);
  119. expectedException.expectMessage(message);
  120. call(params);
  121. }
  122. @DataProvider
  123. public static Object[][] missingOrEmptyParamsAndFailureMessage() {
  124. MapBuilder builder = new MapBuilder()
  125. .put(PARAM_PROJECT, "project key")
  126. .put(PARAM_BRANCH, "branch key")
  127. .put(PARAM_ANALYSIS, "analysis uuid");
  128. return new Object[][] {
  129. {builder.put(PARAM_PROJECT, null).map, "The 'project' parameter is missing"},
  130. {builder.put(PARAM_PROJECT, "").map, "The 'project' parameter is missing"},
  131. {builder.put(PARAM_ANALYSIS, null).map, "The 'analysis' parameter is missing"},
  132. {builder.put(PARAM_ANALYSIS, "").map, "The 'analysis' parameter is missing"},
  133. };
  134. }
  135. @Test
  136. @UseDataProvider("nonexistentParamsAndFailureMessage")
  137. public void fail_with_IAE_when_required_param_nonexistent(Map<String, String> nonexistentParams, String regex) {
  138. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  139. BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
  140. db.components().insertProjectBranch(project, branch);
  141. ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
  142. SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
  143. logInAsProjectAdministrator(project);
  144. Map<String, String> params = new HashMap<>();
  145. params.put(PARAM_PROJECT, project.getKey());
  146. params.put(PARAM_BRANCH, branch.getKey());
  147. params.put(PARAM_ANALYSIS, analysis.getUuid());
  148. params.putAll(nonexistentParams);
  149. expectedException.expect(NotFoundException.class);
  150. expectedException.expectMessage(regexMatcher(regex));
  151. call(params);
  152. }
  153. @DataProvider
  154. public static Object[][] nonexistentParamsAndFailureMessage() {
  155. MapBuilder builder = new MapBuilder();
  156. return new Object[][] {
  157. {builder.put(PARAM_PROJECT, "nonexistent").map, "Component 'nonexistent' on branch .* not found"},
  158. {builder.put(PARAM_BRANCH, "nonexistent").map, "Component .* on branch 'nonexistent' not found"},
  159. {builder.put(PARAM_ANALYSIS, "nonexistent").map, "Analysis 'nonexistent' is not found"},
  160. };
  161. }
  162. @Test
  163. public void fail_when_branch_does_not_belong_to_project() {
  164. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  165. BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
  166. db.components().insertProjectBranch(project, branch);
  167. ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
  168. SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
  169. logInAsProjectAdministrator(project);
  170. ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  171. BranchDto otherBranch = ComponentTesting.newBranchDto(otherProject.projectUuid(), BranchType.LONG);
  172. db.components().insertProjectBranch(otherProject, otherBranch);
  173. ComponentTesting.newProjectBranch(otherProject, otherBranch);
  174. expectedException.expect(NotFoundException.class);
  175. expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", project.getKey(), otherBranch.getKey()));
  176. call(project.getKey(), otherBranch.getKey(), analysis.getUuid());
  177. }
  178. @Test
  179. public void fail_when_analysis_does_not_belong_to_main_branch_of_project() {
  180. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  181. BranchDto branch = new BranchDto()
  182. .setBranchType(BranchType.LONG)
  183. .setProjectUuid(project.uuid())
  184. .setUuid(project.uuid())
  185. .setKey("master");
  186. db.components().insertComponent(project);
  187. db.getDbClient().branchDao().insert(dbSession, branch);
  188. logInAsProjectAdministrator(project);
  189. ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  190. SnapshotDto otherAnalysis = db.components().insertSnapshot(otherProject);
  191. expectedException.expect(IllegalArgumentException.class);
  192. expectedException.expectMessage(String.format("Analysis '%s' does not belong to project '%s'",
  193. otherAnalysis.getUuid(), project.getKey()));
  194. call(ImmutableMap.of(PARAM_PROJECT, project.getKey(), PARAM_ANALYSIS, otherAnalysis.getUuid()));
  195. }
  196. @Test
  197. public void fail_when_analysis_does_not_belong_to_non_main_branch_of_project() {
  198. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  199. BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.LONG);
  200. db.components().insertProjectBranch(project, branch);
  201. logInAsProjectAdministrator(project);
  202. ComponentDto otherProject = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  203. SnapshotDto otherAnalysis = db.components().insertProjectAndSnapshot(otherProject);
  204. expectedException.expect(IllegalArgumentException.class);
  205. expectedException.expectMessage(String.format("Analysis '%s' does not belong to branch '%s' of project '%s'",
  206. otherAnalysis.getUuid(), branch.getKey(), project.getKey()));
  207. call(project.getKey(), branch.getKey(), otherAnalysis.getUuid());
  208. }
  209. @Test
  210. public void fail_when_branch_is_not_long() {
  211. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  212. BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.SHORT);
  213. db.components().insertProjectBranch(project, branch);
  214. ComponentDto branchComponentDto = ComponentTesting.newProjectBranch(project, branch);
  215. SnapshotDto analysis = db.components().insertSnapshot(branchComponentDto);
  216. logInAsProjectAdministrator(project);
  217. expectedException.expect(IllegalArgumentException.class);
  218. expectedException.expectMessage(String.format("Not a long-living branch: '%s'", branch.getKey()));
  219. call(project.getKey(), branch.getKey(), analysis.getUuid());
  220. }
  221. @Test
  222. public void ws_parameters() {
  223. WebService.Action definition = ws.getDef();
  224. assertThat(definition.isPost()).isTrue();
  225. assertThat(definition.key()).isEqualTo("set_baseline");
  226. assertThat(definition.since()).isEqualTo("7.7");
  227. assertThat(definition.isInternal()).isFalse();
  228. }
  229. private void logInAsProjectAdministrator(ComponentDto project) {
  230. userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
  231. }
  232. private void call(Map<String, String> params) {
  233. TestRequest httpRequest = ws.newRequest().setMethod(POST.name());
  234. for (Map.Entry<String, String> param : params.entrySet()) {
  235. httpRequest.setParam(param.getKey(), param.getValue());
  236. }
  237. httpRequest.execute();
  238. }
  239. private void call(String projectKey, @Nullable String branchKey, String analysisUuid) {
  240. if (branchKey == null) {
  241. call(ImmutableMap.of(
  242. PARAM_PROJECT, projectKey,
  243. PARAM_ANALYSIS, analysisUuid));
  244. } else {
  245. call(ImmutableMap.of(
  246. PARAM_PROJECT, projectKey,
  247. PARAM_BRANCH, branchKey,
  248. PARAM_ANALYSIS, analysisUuid));
  249. }
  250. }
  251. private static class MapBuilder {
  252. private final Map<String, String> map;
  253. private MapBuilder() {
  254. this.map = Collections.emptyMap();
  255. }
  256. private MapBuilder(Map<String, String> map) {
  257. this.map = map;
  258. }
  259. public MapBuilder put(String key, @Nullable String value) {
  260. Map<String, String> copy = new HashMap<>(map);
  261. if (value == null) {
  262. copy.remove(key);
  263. } else {
  264. copy.put(key, value);
  265. }
  266. return new MapBuilder(copy);
  267. }
  268. }
  269. }