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.

CreateEventActionTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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 java.util.List;
  22. import java.util.Optional;
  23. import org.junit.Before;
  24. import org.junit.Rule;
  25. import org.junit.Test;
  26. import org.junit.rules.ExpectedException;
  27. import org.sonar.api.server.ws.WebService;
  28. import org.sonar.api.utils.System2;
  29. import org.sonar.api.web.UserRole;
  30. import org.sonar.core.util.UuidFactory;
  31. import org.sonar.core.util.UuidFactoryFast;
  32. import org.sonar.db.DbClient;
  33. import org.sonar.db.DbSession;
  34. import org.sonar.db.DbTester;
  35. import org.sonar.db.component.ComponentDto;
  36. import org.sonar.db.component.ComponentTesting;
  37. import org.sonar.db.component.SnapshotDto;
  38. import org.sonar.db.component.SnapshotTesting;
  39. import org.sonar.db.event.EventDto;
  40. import org.sonar.server.exceptions.ForbiddenException;
  41. import org.sonar.server.exceptions.NotFoundException;
  42. import org.sonar.server.tester.UserSessionRule;
  43. import org.sonar.server.ws.TestRequest;
  44. import org.sonar.server.ws.WsActionTester;
  45. import org.sonarqube.ws.ProjectAnalyses;
  46. import org.sonarqube.ws.ProjectAnalyses.CreateEventResponse;
  47. import static org.assertj.core.api.Assertions.assertThat;
  48. import static org.mockito.Mockito.mock;
  49. import static org.mockito.Mockito.when;
  50. import static org.sonar.db.component.ComponentTesting.newApplication;
  51. import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
  52. import static org.sonar.db.component.ComponentTesting.newView;
  53. import static org.sonar.db.component.SnapshotTesting.newAnalysis;
  54. import static org.sonar.db.component.SnapshotTesting.newSnapshot;
  55. import static org.sonar.test.JsonAssert.assertJson;
  56. import static org.sonarqube.ws.client.WsRequest.Method.POST;
  57. import static org.sonar.server.projectanalysis.ws.EventCategory.OTHER;
  58. import static org.sonar.server.projectanalysis.ws.EventCategory.VERSION;
  59. import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_ANALYSIS;
  60. import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_CATEGORY;
  61. import static org.sonar.server.projectanalysis.ws.ProjectAnalysesWsParameters.PARAM_NAME;
  62. public class CreateEventActionTest {
  63. @Rule
  64. public ExpectedException expectedException = ExpectedException.none();
  65. @Rule
  66. public UserSessionRule userSession = UserSessionRule.standalone();
  67. @Rule
  68. public DbTester db = DbTester.create(System2.INSTANCE);
  69. private DbClient dbClient = db.getDbClient();
  70. private DbSession dbSession = db.getSession();
  71. private UuidFactory uuidFactory = UuidFactoryFast.getInstance();
  72. private System2 system = mock(System2.class);
  73. private WsActionTester ws = new WsActionTester(new CreateEventAction(dbClient, uuidFactory, system, userSession));
  74. @Before
  75. public void setUp() {
  76. when(system.now()).thenReturn(42L);
  77. }
  78. @Test
  79. public void json_example() {
  80. ComponentDto project = db.components().insertPrivateProject();
  81. SnapshotDto analysis = dbClient.snapshotDao().insert(dbSession, SnapshotTesting.newAnalysis(project).setUuid("A2"));
  82. db.commit();
  83. uuidFactory = mock(UuidFactory.class);
  84. when(uuidFactory.create()).thenReturn("E1");
  85. ws = new WsActionTester(new CreateEventAction(dbClient, uuidFactory, system, userSession));
  86. logInAsProjectAdministrator(project);
  87. String result = ws.newRequest()
  88. .setParam(PARAM_ANALYSIS, analysis.getUuid())
  89. .setParam(PARAM_CATEGORY, OTHER.name())
  90. .setParam(PARAM_NAME, "My Custom Event")
  91. .execute().getInput();
  92. assertJson(result).isSimilarTo(getClass().getResource("create_event-example.json"));
  93. }
  94. @Test
  95. public void create_event_in_db() {
  96. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  97. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  98. when(system.now()).thenReturn(123_456_789L);
  99. logInAsProjectAdministrator(project);
  100. CreateEventResponse result = call(VERSION.name(), "5.6.3", analysis.getUuid());
  101. List<EventDto> dbEvents = dbClient.eventDao().selectByComponentUuid(dbSession, analysis.getComponentUuid());
  102. assertThat(dbEvents).hasSize(1);
  103. EventDto dbEvent = dbEvents.get(0);
  104. assertThat(dbEvent.getName()).isEqualTo("5.6.3");
  105. assertThat(dbEvent.getCategory()).isEqualTo(VERSION.getLabel());
  106. assertThat(dbEvent.getDescription()).isNull();
  107. assertThat(dbEvent.getAnalysisUuid()).isEqualTo(analysis.getUuid());
  108. assertThat(dbEvent.getComponentUuid()).isEqualTo(analysis.getComponentUuid());
  109. assertThat(dbEvent.getUuid()).isEqualTo(result.getEvent().getKey());
  110. assertThat(dbEvent.getCreatedAt()).isEqualTo(123_456_789L);
  111. assertThat(dbEvent.getDate()).isEqualTo(analysis.getCreatedAt());
  112. }
  113. @Test
  114. public void create_event_as_project_admin() {
  115. ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "P1");
  116. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  117. logInAsProjectAdministrator(project);
  118. CreateEventResponse result = call(VERSION.name(), "5.6.3", analysis.getUuid());
  119. assertThat(result.getEvent().getKey()).isNotEmpty();
  120. }
  121. @Test
  122. public void create_version_event() {
  123. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  124. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  125. logInAsProjectAdministrator(project);
  126. call(VERSION.name(), "5.6.3", analysis.getUuid());
  127. Optional<SnapshotDto> newAnalysis = dbClient.snapshotDao().selectByUuid(dbSession, analysis.getUuid());
  128. assertThat(newAnalysis.get().getCodePeriodVersion()).isEqualTo("5.6.3");
  129. }
  130. @Test
  131. public void create_other_event_with_ws_response() {
  132. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  133. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  134. logInAsProjectAdministrator(project);
  135. CreateEventResponse result = call(OTHER.name(), "Project Import", analysis.getUuid());
  136. SnapshotDto newAnalysis = dbClient.snapshotDao().selectByUuid(dbSession, analysis.getUuid()).get();
  137. assertThat(analysis.getCodePeriodVersion()).isEqualTo(newAnalysis.getCodePeriodVersion());
  138. ProjectAnalyses.Event wsEvent = result.getEvent();
  139. assertThat(wsEvent.getKey()).isNotEmpty();
  140. assertThat(wsEvent.getCategory()).isEqualTo(OTHER.name());
  141. assertThat(wsEvent.getName()).isEqualTo("Project Import");
  142. assertThat(wsEvent.hasDescription()).isFalse();
  143. assertThat(wsEvent.getAnalysis()).isEqualTo(analysis.getUuid());
  144. }
  145. @Test
  146. public void create_event_without_description() {
  147. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  148. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  149. logInAsProjectAdministrator(project);
  150. CreateEventResponse result = call(OTHER.name(), "Project Import", analysis.getUuid());
  151. ProjectAnalyses.Event event = result.getEvent();
  152. assertThat(event.getKey()).isNotEmpty();
  153. assertThat(event.hasDescription()).isFalse();
  154. }
  155. @Test
  156. public void create_event_on_application() {
  157. ComponentDto application = ComponentTesting.newApplication(db.getDefaultOrganization());
  158. SnapshotDto analysis = db.components().insertProjectAndSnapshot(application);
  159. logInAsProjectAdministrator(application);
  160. CreateEventResponse result = call(OTHER.name(), "Application Event", analysis.getUuid());
  161. ProjectAnalyses.Event event = result.getEvent();
  162. assertThat(event.getName()).isEqualTo("Application Event");
  163. }
  164. @Test
  165. public void create_2_version_events_on_same_project() {
  166. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  167. SnapshotDto firstAnalysis = db.components().insertProjectAndSnapshot(project);
  168. SnapshotDto secondAnalysis = dbClient.snapshotDao().insert(dbSession, newAnalysis(project));
  169. db.commit();
  170. logInAsProjectAdministrator(project);
  171. call(VERSION.name(), "5.6.3", firstAnalysis.getUuid());
  172. call(VERSION.name(), "6.3", secondAnalysis.getUuid());
  173. List<EventDto> events = dbClient.eventDao().selectByComponentUuid(dbSession, project.uuid());
  174. assertThat(events).hasSize(2);
  175. }
  176. @Test
  177. public void fail_if_not_blank_name() {
  178. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  179. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  180. logInAsProjectAdministrator(project);
  181. expectedException.expect(IllegalArgumentException.class);
  182. expectedException.expectMessage("The 'name' parameter is missing");
  183. call(OTHER.name(), " ", analysis.getUuid());
  184. }
  185. @Test
  186. public void fail_if_analysis_is_not_found() {
  187. userSession.logIn();
  188. expectedException.expect(NotFoundException.class);
  189. expectedException.expectMessage("Analysis 'A42' is not found");
  190. call(OTHER.name(), "Project Import", "A42");
  191. }
  192. @Test
  193. public void fail_if_2_version_events_on_the_same_analysis() {
  194. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  195. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  196. logInAsProjectAdministrator(project);
  197. call(VERSION.name(), "5.6.3", analysis.getUuid());
  198. expectedException.expect(IllegalArgumentException.class);
  199. expectedException.expectMessage("A version event already exists on analysis '" + analysis.getUuid() + "'");
  200. call(VERSION.name(), "6.3", analysis.getUuid());
  201. }
  202. @Test
  203. public void fail_if_2_other_events_on_same_analysis_with_same_name() {
  204. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
  205. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  206. logInAsProjectAdministrator(project);
  207. call(OTHER.name(), "Project Import", analysis.getUuid());
  208. expectedException.expect(IllegalArgumentException.class);
  209. expectedException.expectMessage("An 'Other' event with the same name already exists on analysis '" + analysis.getUuid() + "'");
  210. call(OTHER.name(), "Project Import", analysis.getUuid());
  211. }
  212. @Test
  213. public void fail_if_category_other_than_authorized() {
  214. ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
  215. SnapshotDto analysis = db.components().insertProjectAndSnapshot(project);
  216. logInAsProjectAdministrator(project);
  217. expectedException.expect(IllegalArgumentException.class);
  218. ws.newRequest()
  219. .setParam(PARAM_ANALYSIS, analysis.getUuid())
  220. .setParam(PARAM_NAME, "Project Import")
  221. .setParam(PARAM_CATEGORY, "QP")
  222. .execute();
  223. }
  224. @Test
  225. public void fail_if_create_on_view() {
  226. ComponentDto view = newView(db.organizations().insert());
  227. SnapshotDto analysis = db.components().insertViewAndSnapshot(view);
  228. logInAsProjectAdministrator(view);
  229. expectedException.expect(IllegalArgumentException.class);
  230. expectedException.expectMessage("An event must be created on a project or an application");
  231. call(OTHER.name(), "View Event", analysis.getUuid());
  232. }
  233. @Test
  234. public void fail_if_create_version_event_on_application() {
  235. ComponentDto application = newApplication(db.organizations().insert());
  236. SnapshotDto analysis = db.components().insertViewAndSnapshot(application);
  237. logInAsProjectAdministrator(application);
  238. expectedException.expect(IllegalArgumentException.class);
  239. expectedException.expectMessage("A version event must be created on a project");
  240. call(VERSION.name(), "5.6.3", analysis.getUuid());
  241. }
  242. @Test
  243. public void fail_if_project_is_not_found() {
  244. userSession.logIn();
  245. SnapshotDto analysis = dbClient.snapshotDao().insert(dbSession, newSnapshot().setUuid("A1"));
  246. db.commit();
  247. expectedException.expect(IllegalStateException.class);
  248. expectedException.expectMessage("Project of analysis 'A1' is not found");
  249. call(VERSION.name(), "5.6.3", analysis.getUuid());
  250. }
  251. @Test
  252. public void throw_ForbiddenException_if_not_project_administrator() {
  253. SnapshotDto analysis = db.components().insertProjectAndSnapshot(newPrivateProjectDto(db.organizations().insert(), "P1"));
  254. userSession.logIn();
  255. expectedException.expect(ForbiddenException.class);
  256. expectedException.expectMessage("Insufficient privileges");
  257. call(VERSION.name(), "5.6.3", analysis.getUuid());
  258. }
  259. @Test
  260. public void ws_parameters() {
  261. WebService.Action definition = ws.getDef();
  262. assertThat(definition.isPost()).isTrue();
  263. assertThat(definition.key()).isEqualTo("create_event");
  264. assertThat(definition.responseExampleAsString()).isNotEmpty();
  265. }
  266. private void logInAsProjectAdministrator(ComponentDto project) {
  267. userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
  268. }
  269. private CreateEventResponse call(String categoryName, String name, String analysis) {
  270. TestRequest httpRequest = ws.newRequest()
  271. .setMethod(POST.name());
  272. httpRequest.setParam(PARAM_CATEGORY, categoryName)
  273. .setParam(PARAM_NAME, name)
  274. .setParam(PARAM_ANALYSIS, analysis);
  275. return httpRequest.executeProtobuf(CreateEventResponse.class);
  276. }
  277. }