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.

ShowActionTest.java 42KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 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.hotspot.ws;
  21. import com.google.common.collect.ImmutableSet;
  22. import com.google.common.collect.Sets;
  23. import com.tngtech.java.junit.dataprovider.DataProvider;
  24. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  25. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  26. import java.util.Arrays;
  27. import java.util.Collections;
  28. import java.util.List;
  29. import java.util.Random;
  30. import java.util.Set;
  31. import java.util.function.Consumer;
  32. import java.util.stream.Collectors;
  33. import java.util.stream.IntStream;
  34. import java.util.stream.Stream;
  35. import javax.annotation.Nullable;
  36. import org.assertj.core.groups.Tuple;
  37. import org.junit.Rule;
  38. import org.junit.Test;
  39. import org.junit.runner.RunWith;
  40. import org.mockito.ArgumentMatcher;
  41. import org.mockito.Mockito;
  42. import org.sonar.api.issue.Issue;
  43. import org.sonar.api.rules.RuleType;
  44. import org.sonar.api.utils.System2;
  45. import org.sonar.api.web.UserRole;
  46. import org.sonar.db.DbClient;
  47. import org.sonar.db.DbSession;
  48. import org.sonar.db.DbTester;
  49. import org.sonar.db.component.BranchType;
  50. import org.sonar.db.component.ComponentDto;
  51. import org.sonar.db.issue.IssueDto;
  52. import org.sonar.db.protobuf.DbCommons;
  53. import org.sonar.db.protobuf.DbIssues;
  54. import org.sonar.db.rule.RuleDefinitionDto;
  55. import org.sonar.db.rule.RuleTesting;
  56. import org.sonar.db.user.UserDto;
  57. import org.sonar.db.user.UserTesting;
  58. import org.sonar.server.es.EsTester;
  59. import org.sonar.server.exceptions.ForbiddenException;
  60. import org.sonar.server.exceptions.NotFoundException;
  61. import org.sonar.server.issue.AvatarResolver;
  62. import org.sonar.server.issue.AvatarResolverImpl;
  63. import org.sonar.server.issue.IssueChangeWSSupport;
  64. import org.sonar.server.issue.IssueChangeWSSupport.FormattingContext;
  65. import org.sonar.server.issue.IssueChangeWSSupport.Load;
  66. import org.sonar.server.issue.TextRangeResponseFormatter;
  67. import org.sonar.server.issue.ws.UserResponseFormatter;
  68. import org.sonar.server.organization.TestDefaultOrganizationProvider;
  69. import org.sonar.server.security.SecurityStandards;
  70. import org.sonar.server.security.SecurityStandards.SQCategory;
  71. import org.sonar.server.tester.UserSessionRule;
  72. import org.sonar.server.ws.TestRequest;
  73. import org.sonar.server.ws.WsActionTester;
  74. import org.sonarqube.ws.Common;
  75. import org.sonarqube.ws.Common.Changelog.Diff;
  76. import org.sonarqube.ws.Common.User;
  77. import org.sonarqube.ws.Hotspots;
  78. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  79. import static org.assertj.core.api.Assertions.assertThat;
  80. import static org.assertj.core.api.Assertions.assertThatThrownBy;
  81. import static org.assertj.core.api.Assertions.tuple;
  82. import static org.mockito.ArgumentMatchers.any;
  83. import static org.mockito.ArgumentMatchers.anySet;
  84. import static org.mockito.ArgumentMatchers.argThat;
  85. import static org.mockito.ArgumentMatchers.eq;
  86. import static org.mockito.Mockito.verify;
  87. import static org.mockito.Mockito.when;
  88. import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;
  89. import static org.sonar.db.component.ComponentTesting.newFileDto;
  90. @RunWith(DataProviderRunner.class)
  91. public class ShowActionTest {
  92. private static final Random RANDOM = new Random();
  93. @Rule
  94. public DbTester dbTester = DbTester.create(System2.INSTANCE);
  95. @Rule
  96. public EsTester es = EsTester.create();
  97. @Rule
  98. public UserSessionRule userSessionRule = UserSessionRule.standalone();
  99. private DbClient dbClient = dbTester.getDbClient();
  100. private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
  101. private AvatarResolver avatarResolver = new AvatarResolverImpl();
  102. private HotspotWsResponseFormatter responseFormatter = new HotspotWsResponseFormatter(defaultOrganizationProvider);
  103. private IssueChangeWSSupport issueChangeSupport = Mockito.mock(IssueChangeWSSupport.class);
  104. private HotspotWsSupport hotspotWsSupport = new HotspotWsSupport(dbClient, userSessionRule, System2.INSTANCE);
  105. private UserResponseFormatter userFormatter = new UserResponseFormatter(new AvatarResolverImpl());
  106. private TextRangeResponseFormatter textRangeFormatter = new TextRangeResponseFormatter();
  107. private ShowAction underTest = new ShowAction(dbClient, hotspotWsSupport, responseFormatter, textRangeFormatter, userFormatter, issueChangeSupport);
  108. private WsActionTester actionTester = new WsActionTester(underTest);
  109. @Test
  110. public void ws_is_internal() {
  111. assertThat(actionTester.getDef().isInternal()).isTrue();
  112. }
  113. @Test
  114. public void fails_with_IAE_if_parameter_hotspot_is_missing() {
  115. TestRequest request = actionTester.newRequest();
  116. assertThatThrownBy(request::execute)
  117. .isInstanceOf(IllegalArgumentException.class)
  118. .hasMessage("The 'hotspot' parameter is missing");
  119. }
  120. @Test
  121. public void fails_with_NotFoundException_if_hotspot_does_not_exist() {
  122. String key = randomAlphabetic(12);
  123. TestRequest request = actionTester.newRequest()
  124. .setParam("hotspot", key);
  125. assertThatThrownBy(request::execute)
  126. .isInstanceOf(NotFoundException.class)
  127. .hasMessage("Hotspot '%s' does not exist", key);
  128. }
  129. @Test
  130. @UseDataProvider("ruleTypesButHotspot")
  131. public void fails_with_NotFoundException_if_issue_is_not_a_hotspot(RuleType ruleType) {
  132. ComponentDto project = dbTester.components().insertPublicProject();
  133. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  134. RuleDefinitionDto rule = newRule(ruleType);
  135. IssueDto notAHotspot = dbTester.issues().insertIssue(rule, project, file, i -> i.setType(ruleType));
  136. TestRequest request = newRequest(notAHotspot);
  137. assertThatThrownBy(request::execute)
  138. .isInstanceOf(NotFoundException.class)
  139. .hasMessage("Hotspot '%s' does not exist", notAHotspot.getKey());
  140. }
  141. @DataProvider
  142. public static Object[][] ruleTypesButHotspot() {
  143. return Arrays.stream(RuleType.values())
  144. .filter(t -> t != SECURITY_HOTSPOT)
  145. .map(t -> new Object[] {t})
  146. .toArray(Object[][]::new);
  147. }
  148. @Test
  149. public void fails_with_NotFoundException_if_issue_is_hotspot_is_closed() {
  150. ComponentDto project = dbTester.components().insertPublicProject();
  151. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  152. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  153. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setStatus(Issue.STATUS_CLOSED));
  154. TestRequest request = newRequest(hotspot);
  155. assertThatThrownBy(request::execute)
  156. .isInstanceOf(NotFoundException.class)
  157. .hasMessage("Hotspot '%s' does not exist", hotspot.getKey());
  158. }
  159. @Test
  160. public void fails_with_ForbiddenException_if_project_is_private_and_not_allowed() {
  161. ComponentDto project = dbTester.components().insertPrivateProject();
  162. userSessionRule.registerComponents(project);
  163. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  164. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  165. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  166. TestRequest request = newRequest(hotspot);
  167. assertThatThrownBy(request::execute)
  168. .isInstanceOf(ForbiddenException.class)
  169. .hasMessage("Insufficient privileges");
  170. }
  171. @Test
  172. public void succeeds_on_public_project() {
  173. ComponentDto project = dbTester.components().insertPublicProject();
  174. userSessionRule.registerComponents(project);
  175. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  176. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  177. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  178. mockChangelogAndCommentsFormattingContext();
  179. Hotspots.ShowWsResponse response = newRequest(hotspot)
  180. .executeProtobuf(Hotspots.ShowWsResponse.class);
  181. assertThat(response.getKey()).isEqualTo(hotspot.getKey());
  182. }
  183. @Test
  184. public void succeeds_on_private_project_with_permission() {
  185. ComponentDto project = dbTester.components().insertPrivateProject();
  186. userSessionRule.registerComponents(project);
  187. userSessionRule.logIn().addProjectPermission(UserRole.USER, project);
  188. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  189. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  190. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  191. mockChangelogAndCommentsFormattingContext();
  192. Hotspots.ShowWsResponse response = newRequest(hotspot)
  193. .executeProtobuf(Hotspots.ShowWsResponse.class);
  194. assertThat(response.getKey()).isEqualTo(hotspot.getKey());
  195. }
  196. @Test
  197. public void return_canChangeStatus_false_on_public_project_when_anonymous() {
  198. ComponentDto project = dbTester.components().insertPublicProject();
  199. userSessionRule.registerComponents(project);
  200. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  201. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  202. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  203. mockChangelogAndCommentsFormattingContext();
  204. Hotspots.ShowWsResponse response = newRequest(hotspot)
  205. .executeProtobuf(Hotspots.ShowWsResponse.class);
  206. assertThat(response.getCanChangeStatus()).isFalse();
  207. }
  208. @Test
  209. @UseDataProvider("allPublicProjectPermissionsButSECURITYHOTSPOT_ADMIN")
  210. public void return_canChangeStatus_false_on_public_project_when_authenticated_without_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) {
  211. ComponentDto project = dbTester.components().insertPublicProject();
  212. userSessionRule.logIn().registerComponents(project);
  213. if (permission != null) {
  214. userSessionRule.addProjectPermission(permission, project);
  215. }
  216. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  217. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  218. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  219. mockChangelogAndCommentsFormattingContext();
  220. Hotspots.ShowWsResponse response = newRequest(hotspot)
  221. .executeProtobuf(Hotspots.ShowWsResponse.class);
  222. assertThat(response.getCanChangeStatus()).isFalse();
  223. }
  224. @Test
  225. @UseDataProvider("allPublicProjectPermissionsButSECURITYHOTSPOT_ADMIN")
  226. public void return_canChangeStatus_true_on_public_project_when_authenticated_with_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) {
  227. ComponentDto project = dbTester.components().insertPublicProject();
  228. userSessionRule.registerComponents(project)
  229. .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, project);
  230. if (permission != null) {
  231. userSessionRule.addProjectPermission(permission, project);
  232. }
  233. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  234. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  235. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  236. mockChangelogAndCommentsFormattingContext();
  237. Hotspots.ShowWsResponse response = newRequest(hotspot)
  238. .executeProtobuf(Hotspots.ShowWsResponse.class);
  239. assertThat(response.getCanChangeStatus()).isTrue();
  240. }
  241. @DataProvider
  242. public static Object[][] allPublicProjectPermissionsButSECURITYHOTSPOT_ADMIN() {
  243. return new Object[][] {
  244. {null}, // no permission
  245. {UserRole.ADMIN},
  246. {UserRole.SCAN},
  247. {UserRole.ISSUE_ADMIN}
  248. };
  249. }
  250. @Test
  251. @UseDataProvider("allPrivateProjectPermissionsButSECURITYHOTSPOT_ADMIN_and_USER")
  252. public void return_canChangeStatus_false_on_private_project_without_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) {
  253. ComponentDto project = dbTester.components().insertPrivateProject();
  254. userSessionRule
  255. .registerComponents(project)
  256. .logIn()
  257. .addProjectPermission(UserRole.USER, project);
  258. if (permission != null) {
  259. userSessionRule.addProjectPermission(permission, project);
  260. }
  261. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  262. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  263. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  264. mockChangelogAndCommentsFormattingContext();
  265. Hotspots.ShowWsResponse response = newRequest(hotspot)
  266. .executeProtobuf(Hotspots.ShowWsResponse.class);
  267. assertThat(response.getCanChangeStatus()).isFalse();
  268. }
  269. @Test
  270. @UseDataProvider("allPrivateProjectPermissionsButSECURITYHOTSPOT_ADMIN_and_USER")
  271. public void return_canChangeStatus_false_on_private_project_with_SECURITYHOTSPOT_ADMIN_permission(@Nullable String permission) {
  272. ComponentDto project = dbTester.components().insertPrivateProject();
  273. userSessionRule
  274. .registerComponents(project)
  275. .logIn()
  276. .addProjectPermission(UserRole.USER, project)
  277. .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, project);
  278. if (permission != null) {
  279. userSessionRule.addProjectPermission(permission, project);
  280. }
  281. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  282. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  283. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  284. mockChangelogAndCommentsFormattingContext();
  285. Hotspots.ShowWsResponse response = newRequest(hotspot)
  286. .executeProtobuf(Hotspots.ShowWsResponse.class);
  287. assertThat(response.getCanChangeStatus()).isTrue();
  288. }
  289. @DataProvider
  290. public static Object[][] allPrivateProjectPermissionsButSECURITYHOTSPOT_ADMIN_and_USER() {
  291. return new Object[][] {
  292. {null}, // only USER permission
  293. {UserRole.CODEVIEWER},
  294. {UserRole.ADMIN},
  295. {UserRole.SCAN},
  296. {UserRole.ISSUE_ADMIN}
  297. };
  298. }
  299. @Test
  300. @UseDataProvider("statusAndResolutionCombinations")
  301. public void returns_status_and_resolution(String status, @Nullable String resolution) {
  302. ComponentDto project = dbTester.components().insertPrivateProject();
  303. userSessionRule.registerComponents(project);
  304. userSessionRule.logIn().addProjectPermission(UserRole.USER, project);
  305. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  306. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  307. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setStatus(status).setResolution(resolution));
  308. mockChangelogAndCommentsFormattingContext();
  309. Hotspots.ShowWsResponse response = newRequest(hotspot)
  310. .executeProtobuf(Hotspots.ShowWsResponse.class);
  311. assertThat(response.getStatus()).isEqualTo(status);
  312. if (resolution == null) {
  313. assertThat(response.hasResolution()).isFalse();
  314. } else {
  315. assertThat(response.getResolution()).isEqualTo(resolution);
  316. }
  317. }
  318. @DataProvider
  319. public static Object[][] statusAndResolutionCombinations() {
  320. return new Object[][] {
  321. {Issue.STATUS_TO_REVIEW, null},
  322. {Issue.STATUS_REVIEWED, Issue.RESOLUTION_FIXED},
  323. {Issue.STATUS_REVIEWED, Issue.RESOLUTION_SAFE}
  324. };
  325. }
  326. @Test
  327. public void returns_hotspot_component_and_rule() {
  328. ComponentDto project = dbTester.components().insertPublicProject();
  329. userSessionRule.registerComponents(project);
  330. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  331. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  332. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  333. mockChangelogAndCommentsFormattingContext();
  334. Hotspots.ShowWsResponse response = newRequest(hotspot)
  335. .executeProtobuf(Hotspots.ShowWsResponse.class);
  336. assertThat(response.getKey()).isEqualTo(hotspot.getKey());
  337. verifyComponent(response.getComponent(), file, null, null);
  338. verifyComponent(response.getProject(), project, null, null);
  339. verifyRule(response.getRule(), rule);
  340. assertThat(response.hasTextRange()).isFalse();
  341. }
  342. @Test
  343. public void returns_no_textRange_when_locations_have_none() {
  344. ComponentDto project = dbTester.components().insertPublicProject();
  345. userSessionRule.registerComponents(project);
  346. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  347. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  348. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file,
  349. t -> t.setLocations(DbIssues.Locations.newBuilder().build()));
  350. mockChangelogAndCommentsFormattingContext();
  351. Hotspots.ShowWsResponse response = newRequest(hotspot)
  352. .executeProtobuf(Hotspots.ShowWsResponse.class);
  353. assertThat(response.hasTextRange()).isFalse();
  354. }
  355. @Test
  356. @UseDataProvider("randomTextRangeValues")
  357. public void returns_textRange(int startLine, int endLine, int startOffset, int endOffset) {
  358. ComponentDto project = dbTester.components().insertPublicProject();
  359. userSessionRule.registerComponents(project);
  360. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  361. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  362. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file,
  363. t -> t.setLocations(DbIssues.Locations.newBuilder()
  364. .setTextRange(DbCommons.TextRange.newBuilder()
  365. .setStartLine(startLine)
  366. .setEndLine(endLine)
  367. .setStartOffset(startOffset)
  368. .setEndOffset(endOffset)
  369. .build())
  370. .build()));
  371. mockChangelogAndCommentsFormattingContext();
  372. Hotspots.ShowWsResponse response = newRequest(hotspot)
  373. .executeProtobuf(Hotspots.ShowWsResponse.class);
  374. assertThat(response.hasTextRange()).isTrue();
  375. Common.TextRange textRange = response.getTextRange();
  376. assertThat(textRange.getStartLine()).isEqualTo(startLine);
  377. assertThat(textRange.getEndLine()).isEqualTo(endLine);
  378. assertThat(textRange.getStartOffset()).isEqualTo(startOffset);
  379. assertThat(textRange.getEndOffset()).isEqualTo(endOffset);
  380. }
  381. @Test
  382. public void returns_no_assignee_when_user_does_not_exist() {
  383. ComponentDto project = dbTester.components().insertPublicProject();
  384. userSessionRule.registerComponents(project);
  385. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  386. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  387. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAssigneeUuid(randomAlphabetic(10)));
  388. mockChangelogAndCommentsFormattingContext();
  389. Hotspots.ShowWsResponse response = newRequest(hotspot)
  390. .executeProtobuf(Hotspots.ShowWsResponse.class);
  391. assertThat(response.hasAssignee()).isFalse();
  392. }
  393. @Test
  394. public void returns_assignee_details_when_user_exists() {
  395. ComponentDto project = dbTester.components().insertPublicProject();
  396. userSessionRule.registerComponents(project);
  397. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  398. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  399. UserDto assignee = dbTester.users().insertUser();
  400. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAssigneeUuid(assignee.getUuid()));
  401. mockChangelogAndCommentsFormattingContext();
  402. Hotspots.ShowWsResponse response = newRequest(hotspot)
  403. .executeProtobuf(Hotspots.ShowWsResponse.class);
  404. assertThat(response.getAssignee()).isEqualTo(assignee.getLogin());
  405. assertThat(response.getUsersList()).hasSize(1);
  406. User wsAssignee = response.getUsersList().iterator().next();
  407. assertThat(wsAssignee.getLogin()).isEqualTo(assignee.getLogin());
  408. assertThat(wsAssignee.getName()).isEqualTo(assignee.getName());
  409. assertThat(wsAssignee.getActive()).isEqualTo(assignee.isActive());
  410. assertThat(wsAssignee.getAvatar()).isEqualTo(avatarResolver.create(assignee));
  411. }
  412. @Test
  413. public void returns_no_avatar_if_assignee_has_no_email() {
  414. ComponentDto project = dbTester.components().insertPublicProject();
  415. userSessionRule.registerComponents(project);
  416. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  417. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  418. UserDto assignee = dbTester.users().insertUser(t -> t.setEmail(null));
  419. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAssigneeUuid(assignee.getUuid()));
  420. mockChangelogAndCommentsFormattingContext();
  421. Hotspots.ShowWsResponse response = newRequest(hotspot)
  422. .executeProtobuf(Hotspots.ShowWsResponse.class);
  423. assertThat(response.getUsersList()).hasSize(1);
  424. assertThat(response.getUsersList().iterator().next().hasAvatar()).isFalse();
  425. }
  426. @Test
  427. public void returns_inactive_when_assignee_is_inactive() {
  428. ComponentDto project = dbTester.components().insertPublicProject();
  429. userSessionRule.registerComponents(project);
  430. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  431. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  432. UserDto assignee = dbTester.users().insertUser(t -> t.setActive(false));
  433. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAssigneeUuid(assignee.getUuid()));
  434. mockChangelogAndCommentsFormattingContext();
  435. Hotspots.ShowWsResponse response = newRequest(hotspot)
  436. .executeProtobuf(Hotspots.ShowWsResponse.class);
  437. assertThat(response.getUsersList()).hasSize(1);
  438. assertThat(response.getUsersList().iterator().next().getActive()).isFalse();
  439. }
  440. @Test
  441. public void returns_author_login_when_user_does_not_exist() {
  442. ComponentDto project = dbTester.components().insertPublicProject();
  443. userSessionRule.registerComponents(project);
  444. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  445. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  446. String authorLogin = randomAlphabetic(10);
  447. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAuthorLogin(authorLogin));
  448. mockChangelogAndCommentsFormattingContext();
  449. Hotspots.ShowWsResponse response = newRequest(hotspot)
  450. .executeProtobuf(Hotspots.ShowWsResponse.class);
  451. assertThat(response.getUsersList()).isEmpty();
  452. assertThat(response.getAuthor()).isEqualTo(authorLogin);
  453. }
  454. @Test
  455. public void returns_author_details_when_user_exists() {
  456. ComponentDto project = dbTester.components().insertPublicProject();
  457. userSessionRule.registerComponents(project);
  458. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  459. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  460. UserDto author = dbTester.users().insertUser();
  461. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAuthorLogin(author.getLogin()));
  462. mockChangelogAndCommentsFormattingContext();
  463. Hotspots.ShowWsResponse response = newRequest(hotspot)
  464. .executeProtobuf(Hotspots.ShowWsResponse.class);
  465. assertThat(response.getAuthor()).isEqualTo(author.getLogin());
  466. User wsAuthorFromList = response.getUsersList().iterator().next();
  467. assertThat(wsAuthorFromList.getLogin()).isEqualTo(author.getLogin());
  468. assertThat(wsAuthorFromList.getName()).isEqualTo(author.getName());
  469. assertThat(wsAuthorFromList.getActive()).isEqualTo(author.isActive());
  470. assertThat(wsAuthorFromList.getAvatar()).isEqualTo(avatarResolver.create(author));
  471. }
  472. @Test
  473. public void returns_no_avatar_if_author_has_no_email() {
  474. ComponentDto project = dbTester.components().insertPublicProject();
  475. userSessionRule.registerComponents(project);
  476. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  477. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  478. UserDto author = dbTester.users().insertUser(t -> t.setEmail(null));
  479. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAuthorLogin(author.getLogin()));
  480. mockChangelogAndCommentsFormattingContext();
  481. Hotspots.ShowWsResponse response = newRequest(hotspot)
  482. .executeProtobuf(Hotspots.ShowWsResponse.class);
  483. assertThat(response.getUsersList()).hasSize(1);
  484. assertThat(response.getUsersList().iterator().next().hasAvatar()).isFalse();
  485. }
  486. @Test
  487. public void returns_inactive_if_author_is_inactive() {
  488. ComponentDto project = dbTester.components().insertPublicProject();
  489. userSessionRule.registerComponents(project);
  490. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  491. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  492. UserDto author = dbTester.users().insertUser(t -> t.setActive(false));
  493. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, t -> t.setAuthorLogin(author.getLogin()));
  494. mockChangelogAndCommentsFormattingContext();
  495. Hotspots.ShowWsResponse response = newRequest(hotspot)
  496. .executeProtobuf(Hotspots.ShowWsResponse.class);
  497. assertThat(response.getUsersList()).hasSize(1);
  498. assertThat(response.getUsersList().iterator().next().getActive()).isFalse();
  499. }
  500. @DataProvider
  501. public static Object[][] randomTextRangeValues() {
  502. int startLine = RANDOM.nextInt(200);
  503. int endLine = RANDOM.nextInt(200);
  504. int startOffset = RANDOM.nextInt(200);
  505. int endOffset = RANDOM.nextInt(200);
  506. return new Object[][] {
  507. {startLine, endLine, startOffset, endOffset}
  508. };
  509. }
  510. @Test
  511. public void returns_textRange_missing_fields() {
  512. ComponentDto project = dbTester.components().insertPublicProject();
  513. userSessionRule.registerComponents(project);
  514. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  515. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  516. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file,
  517. t -> t.setLocations(DbIssues.Locations.newBuilder()
  518. .setTextRange(DbCommons.TextRange.newBuilder().build())
  519. .build()));
  520. mockChangelogAndCommentsFormattingContext();
  521. Hotspots.ShowWsResponse response = newRequest(hotspot)
  522. .executeProtobuf(Hotspots.ShowWsResponse.class);
  523. assertThat(response.hasTextRange()).isTrue();
  524. Common.TextRange textRange = response.getTextRange();
  525. assertThat(textRange.hasStartLine()).isFalse();
  526. assertThat(textRange.hasEndLine()).isFalse();
  527. assertThat(textRange.hasStartOffset()).isFalse();
  528. assertThat(textRange.hasEndOffset()).isFalse();
  529. }
  530. @Test
  531. @UseDataProvider("allSQCategoryAndVulnerabilityProbability")
  532. public void returns_securityCategory_and_vulnerabilityProbability_of_rule(Set<String> standards,
  533. SQCategory expected) {
  534. ComponentDto project = dbTester.components().insertPublicProject();
  535. userSessionRule.registerComponents(project);
  536. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  537. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT, t -> t.setSecurityStandards(standards));
  538. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file,
  539. t -> t.setLocations(DbIssues.Locations.newBuilder()
  540. .setTextRange(DbCommons.TextRange.newBuilder().build())
  541. .build()));
  542. mockChangelogAndCommentsFormattingContext();
  543. Hotspots.ShowWsResponse response = newRequest(hotspot)
  544. .executeProtobuf(Hotspots.ShowWsResponse.class);
  545. Hotspots.Rule wsRule = response.getRule();
  546. assertThat(wsRule.getSecurityCategory()).isEqualTo(expected.getKey());
  547. assertThat(wsRule.getVulnerabilityProbability()).isEqualTo(expected.getVulnerability().name());
  548. }
  549. @DataProvider
  550. public static Object[][] allSQCategoryAndVulnerabilityProbability() {
  551. Stream<Object[]> allButOthers = SecurityStandards.CWES_BY_SQ_CATEGORY
  552. .entrySet()
  553. .stream()
  554. .map(t -> new Object[] {
  555. t.getValue().stream().map(s -> "cwe:" + s).collect(Collectors.toSet()),
  556. t.getKey()
  557. });
  558. Stream<Object[]> others = Stream.of(
  559. new Object[] {Collections.emptySet(), SQCategory.OTHERS},
  560. new Object[] {ImmutableSet.of("foo", "bar", "acme"), SQCategory.OTHERS});
  561. return Stream.concat(allButOthers, others)
  562. .toArray(Object[][]::new);
  563. }
  564. @Test
  565. public void returns_project_twice_when_hotspot_on_project() {
  566. ComponentDto project = dbTester.components().insertPublicProject();
  567. userSessionRule.registerComponents(project);
  568. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  569. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, project,
  570. t -> t.setLocations(DbIssues.Locations.newBuilder()
  571. .setTextRange(DbCommons.TextRange.newBuilder().build())
  572. .build()));
  573. mockChangelogAndCommentsFormattingContext();
  574. Hotspots.ShowWsResponse response = newRequest(hotspot)
  575. .executeProtobuf(Hotspots.ShowWsResponse.class);
  576. verifyComponent(response.getProject(), project, null, null);
  577. verifyComponent(response.getComponent(), project, null, null);
  578. }
  579. @Test
  580. public void returns_branch_but_no_pullRequest_on_component_and_project_on_non_main_branch() {
  581. ComponentDto project = dbTester.components().insertPublicProject();
  582. ComponentDto branch = dbTester.components().insertProjectBranch(project);
  583. ComponentDto file = dbTester.components().insertComponent(newFileDto(branch));
  584. userSessionRule.registerComponents(project);
  585. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  586. IssueDto hotspot = dbTester.issues().insertHotspot(rule, branch, file,
  587. t -> t.setLocations(DbIssues.Locations.newBuilder()
  588. .setTextRange(DbCommons.TextRange.newBuilder().build())
  589. .build()));
  590. mockChangelogAndCommentsFormattingContext();
  591. Hotspots.ShowWsResponse response = newRequest(hotspot)
  592. .executeProtobuf(Hotspots.ShowWsResponse.class);
  593. verifyComponent(response.getProject(), branch, branch.getBranch(), null);
  594. verifyComponent(response.getComponent(), file, branch.getBranch(), null);
  595. }
  596. @Test
  597. public void returns_pullRequest_but_no_branch_on_component_and_project_on_pullRequest() {
  598. ComponentDto project = dbTester.components().insertPublicProject();
  599. ComponentDto pullRequest = dbTester.components().insertProjectBranch(project,
  600. t -> t.setBranchType(BranchType.PULL_REQUEST));
  601. ComponentDto file = dbTester.components().insertComponent(newFileDto(pullRequest));
  602. userSessionRule.registerComponents(project);
  603. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  604. IssueDto hotspot = dbTester.issues().insertHotspot(rule, pullRequest, file,
  605. t -> t.setLocations(DbIssues.Locations.newBuilder()
  606. .setTextRange(DbCommons.TextRange.newBuilder().build())
  607. .build()));
  608. mockChangelogAndCommentsFormattingContext();
  609. Hotspots.ShowWsResponse response = newRequest(hotspot)
  610. .executeProtobuf(Hotspots.ShowWsResponse.class);
  611. verifyComponent(response.getProject(), pullRequest, null, pullRequest.getPullRequest());
  612. verifyComponent(response.getComponent(), file, null, pullRequest.getPullRequest());
  613. }
  614. @Test
  615. public void returns_hotspot_changelog_and_comments() {
  616. ComponentDto project = dbTester.components().insertPublicProject();
  617. userSessionRule.registerComponents(project);
  618. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  619. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  620. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file,
  621. t -> t.setLocations(DbIssues.Locations.newBuilder()
  622. .setTextRange(DbCommons.TextRange.newBuilder().build())
  623. .build()));
  624. List<Common.Changelog> changelog = IntStream.range(0, 1 + new Random().nextInt(12))
  625. .mapToObj(i -> Common.Changelog.newBuilder().setUser("u" + i).build())
  626. .collect(Collectors.toList());
  627. List<Common.Comment> comments = IntStream.range(0, 1 + new Random().nextInt(12))
  628. .mapToObj(i -> Common.Comment.newBuilder().setKey("u" + i).build())
  629. .collect(Collectors.toList());
  630. FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext();
  631. when(issueChangeSupport.formatChangelog(any(), any())).thenReturn(changelog.stream());
  632. when(issueChangeSupport.formatComments(any(), any(), any())).thenReturn(comments.stream());
  633. Hotspots.ShowWsResponse response = newRequest(hotspot)
  634. .executeProtobuf(Hotspots.ShowWsResponse.class);
  635. assertThat(response.getChangelogList())
  636. .extracting(Common.Changelog::getUser)
  637. .containsExactly(changelog.stream().map(Common.Changelog::getUser).toArray(String[]::new));
  638. assertThat(response.getCommentList())
  639. .extracting(Common.Comment::getKey)
  640. .containsExactly(comments.stream().map(Common.Comment::getKey).toArray(String[]::new));
  641. verify(issueChangeSupport).newFormattingContext(any(DbSession.class),
  642. argThat(new IssueDtoSetArgumentMatcher(hotspot)),
  643. eq(Load.ALL),
  644. eq(Collections.emptySet()), eq(ImmutableSet.of(project, file)));
  645. verify(issueChangeSupport).formatChangelog(argThat(new IssueDtoArgumentMatcher(hotspot)), eq(formattingContext));
  646. verify(issueChangeSupport).formatComments(argThat(new IssueDtoArgumentMatcher(hotspot)), any(Common.Comment.Builder.class), eq(formattingContext));
  647. }
  648. @Test
  649. public void returns_user_details_of_users_from_ChangelogAndComments() {
  650. ComponentDto project = dbTester.components().insertPublicProject();
  651. userSessionRule.registerComponents(project);
  652. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  653. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  654. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file);
  655. FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext();
  656. Set<UserDto> changeLogAndCommentsUsers = IntStream.range(0, 1 + RANDOM.nextInt(14))
  657. .mapToObj(i -> UserTesting.newUserDto())
  658. .collect(Collectors.toSet());
  659. when(formattingContext.getUsers()).thenReturn(changeLogAndCommentsUsers);
  660. Hotspots.ShowWsResponse response = newRequest(hotspot)
  661. .executeProtobuf(Hotspots.ShowWsResponse.class);
  662. assertThat(response.getUsersList())
  663. .extracting(User::getLogin, User::getName, User::getActive)
  664. .containsExactlyInAnyOrder(
  665. changeLogAndCommentsUsers.stream()
  666. .map(t -> tuple(t.getLogin(), t.getName(), t.isActive()))
  667. .toArray(Tuple[]::new));
  668. }
  669. @Test
  670. public void returns_user_of_users_from_ChangelogAndComments_and_assignee_and_author() {
  671. ComponentDto project = dbTester.components().insertPublicProject();
  672. userSessionRule.registerComponents(project);
  673. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  674. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  675. UserDto author = dbTester.users().insertUser();
  676. UserDto assignee = dbTester.users().insertUser();
  677. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file,
  678. t -> t.setAuthorLogin(author.getLogin())
  679. .setAssigneeUuid(assignee.getUuid()));
  680. FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext();
  681. Set<UserDto> changeLogAndCommentsUsers = IntStream.range(0, 1 + RANDOM.nextInt(14))
  682. .mapToObj(i -> UserTesting.newUserDto())
  683. .collect(Collectors.toSet());
  684. when(formattingContext.getUsers()).thenReturn(changeLogAndCommentsUsers);
  685. Hotspots.ShowWsResponse response = newRequest(hotspot)
  686. .executeProtobuf(Hotspots.ShowWsResponse.class);
  687. assertThat(response.getUsersList())
  688. .extracting(User::getLogin, User::getName, User::getActive)
  689. .containsExactlyInAnyOrder(
  690. Stream.concat(
  691. Stream.of(author, assignee),
  692. changeLogAndCommentsUsers.stream())
  693. .map(t -> tuple(t.getLogin(), t.getName(), t.isActive()))
  694. .toArray(Tuple[]::new));
  695. }
  696. @Test
  697. public void do_not_duplicate_user_if_author_assignee_ChangeLogComment_user() {
  698. ComponentDto project = dbTester.components().insertPublicProject();
  699. userSessionRule.registerComponents(project);
  700. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
  701. ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
  702. UserDto author = dbTester.users().insertUser();
  703. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file,
  704. t -> t.setAuthorLogin(author.getLogin())
  705. .setAssigneeUuid(author.getUuid()));
  706. FormattingContext formattingContext = mockChangelogAndCommentsFormattingContext();
  707. when(formattingContext.getUsers()).thenReturn(ImmutableSet.of(author));
  708. Hotspots.ShowWsResponse response = newRequest(hotspot)
  709. .executeProtobuf(Hotspots.ShowWsResponse.class);
  710. assertThat(response.getUsersList())
  711. .extracting(User::getLogin, User::getName, User::getActive)
  712. .containsOnly(tuple(author.getLogin(), author.getName(), author.isActive()));
  713. }
  714. @Test
  715. public void verify_response_example() {
  716. ComponentDto project = dbTester.components().insertPublicProject(componentDto -> componentDto
  717. .setName("test-project")
  718. .setLongName("test-project")
  719. .setDbKey("com.sonarsource:test-project"));
  720. userSessionRule.registerComponents(project)
  721. .addProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN, project);
  722. ComponentDto file = dbTester.components().insertComponent(
  723. newFileDto(project)
  724. .setDbKey("com.sonarsource:test-project:src/main/java/com/sonarsource/FourthClass.java")
  725. .setName("FourthClass.java")
  726. .setLongName("src/main/java/com/sonarsource/FourthClass.java")
  727. .setPath("src/main/java/com/sonarsource/FourthClass.java"));
  728. UserDto author = dbTester.users().insertUser(u -> u.setLogin("joe")
  729. .setName("Joe"));
  730. long time = 1577976190000L;
  731. RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT, r -> r.setRuleKey("S4787")
  732. .setRepositoryKey("java")
  733. .setName("rule-name")
  734. .setSecurityStandards(Sets.newHashSet(SQCategory.WEAK_CRYPTOGRAPHY.getKey())));
  735. IssueDto hotspot = dbTester.issues().insertHotspot(rule, project, file, h -> h
  736. .setAssigneeUuid("assignee-uuid")
  737. .setAuthorLogin("joe")
  738. .setMessage("message")
  739. .setLine(10)
  740. .setIssueCreationTime(time)
  741. .setIssueUpdateTime(time)
  742. .setAuthorLogin(author.getLogin())
  743. .setAssigneeUuid(author.getUuid())
  744. .setKee("AW9mgJw6eFC3pGl94Wrf"));
  745. List<Common.Changelog> changelog = IntStream.range(0, 3)
  746. .mapToObj(i -> Common.Changelog.newBuilder()
  747. .setUser("joe")
  748. .setCreationDate("2020-01-02T14:44:55+0100")
  749. .addDiffs(Diff.newBuilder().setKey("diff-key-" + i).setNewValue("new-value-" + i).setOldValue("old-value-" + i))
  750. .setIsUserActive(true)
  751. .setUserName("Joe")
  752. .setAvatar("my-avatar")
  753. .build())
  754. .collect(Collectors.toList());
  755. List<Common.Comment> comments = IntStream.range(0, 3)
  756. .mapToObj(i -> Common.Comment.newBuilder()
  757. .setKey("comment-" + i)
  758. .setHtmlText("html text " + i)
  759. .setLogin("Joe")
  760. .setMarkdown("markdown " + i)
  761. .setCreatedAt("2020-01-02T14:47:47+0100")
  762. .build())
  763. .collect(Collectors.toList());
  764. mockChangelogAndCommentsFormattingContext();
  765. when(issueChangeSupport.formatChangelog(any(), any())).thenReturn(changelog.stream());
  766. when(issueChangeSupport.formatComments(any(), any(), any())).thenReturn(comments.stream());
  767. newRequest(hotspot)
  768. .execute()
  769. .assertJson(actionTester.getDef().responseExampleAsString()
  770. .replaceAll("default-organization", dbTester.getDefaultOrganization().getKey()));
  771. }
  772. private FormattingContext mockChangelogAndCommentsFormattingContext() {
  773. FormattingContext formattingContext = Mockito.mock(FormattingContext.class);
  774. when(issueChangeSupport.newFormattingContext(any(), any(), any(), anySet(), anySet())).thenReturn(formattingContext);
  775. return formattingContext;
  776. }
  777. private void verifyRule(Hotspots.Rule wsRule, RuleDefinitionDto dto) {
  778. assertThat(wsRule.getKey()).isEqualTo(dto.getKey().toString());
  779. assertThat(wsRule.getName()).isEqualTo(dto.getName());
  780. assertThat(wsRule.getSecurityCategory()).isEqualTo(SQCategory.OTHERS.getKey());
  781. assertThat(wsRule.getVulnerabilityProbability()).isEqualTo(SQCategory.OTHERS.getVulnerability().name());
  782. }
  783. private static void verifyComponent(Hotspots.Component wsComponent, ComponentDto dto, @Nullable String branch, @Nullable String pullRequest) {
  784. assertThat(wsComponent.getKey()).isEqualTo(dto.getKey());
  785. if (dto.path() == null) {
  786. assertThat(wsComponent.hasPath()).isFalse();
  787. } else {
  788. assertThat(wsComponent.getPath()).isEqualTo(dto.path());
  789. }
  790. assertThat(wsComponent.getQualifier()).isEqualTo(dto.qualifier());
  791. assertThat(wsComponent.getName()).isEqualTo(dto.name());
  792. assertThat(wsComponent.getLongName()).isEqualTo(dto.longName());
  793. if (branch == null) {
  794. assertThat(wsComponent.hasBranch()).isFalse();
  795. } else {
  796. assertThat(wsComponent.getBranch()).isEqualTo(branch);
  797. }
  798. if (pullRequest == null) {
  799. assertThat(wsComponent.hasPullRequest()).isFalse();
  800. } else {
  801. assertThat(wsComponent.getPullRequest()).isEqualTo(pullRequest);
  802. }
  803. }
  804. private TestRequest newRequest(IssueDto hotspot) {
  805. return actionTester.newRequest()
  806. .setParam("hotspot", hotspot.getKey());
  807. }
  808. private RuleDefinitionDto newRule(RuleType ruleType) {
  809. return newRule(ruleType, t -> {
  810. });
  811. }
  812. private RuleDefinitionDto newRule(RuleType ruleType, Consumer<RuleDefinitionDto> populate) {
  813. RuleDefinitionDto ruleDefinition = RuleTesting.newRule()
  814. .setType(ruleType);
  815. populate.accept(ruleDefinition);
  816. dbTester.rules().insert(ruleDefinition);
  817. return ruleDefinition;
  818. }
  819. private static class IssueDtoSetArgumentMatcher implements ArgumentMatcher<Set<IssueDto>> {
  820. private final IssueDto expected;
  821. private IssueDtoSetArgumentMatcher(IssueDto expected) {
  822. this.expected = expected;
  823. }
  824. @Override
  825. public boolean matches(Set<IssueDto> argument) {
  826. return argument != null && argument.size() == 1 && argument.iterator().next().getKey().equals(expected.getKey());
  827. }
  828. @Override
  829. public String toString() {
  830. return "Set<IssueDto>[" + expected.getKey() + "]";
  831. }
  832. }
  833. private static class IssueDtoArgumentMatcher implements ArgumentMatcher<IssueDto> {
  834. private final IssueDto expected;
  835. private IssueDtoArgumentMatcher(IssueDto expected) {
  836. this.expected = expected;
  837. }
  838. @Override
  839. public boolean matches(IssueDto argument) {
  840. return argument != null && argument.getKey().equals(expected.getKey());
  841. }
  842. @Override
  843. public String toString() {
  844. return "IssueDto[key=" + expected.getKey() + "]";
  845. }
  846. }
  847. }