Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

IssueDaoTest.java 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 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.db.issue;
  21. import java.util.Arrays;
  22. import java.util.Collection;
  23. import java.util.Collections;
  24. import java.util.List;
  25. import java.util.stream.Stream;
  26. import org.junit.Rule;
  27. import org.junit.Test;
  28. import org.junit.rules.ExpectedException;
  29. import org.sonar.api.issue.Issue;
  30. import org.sonar.api.rule.RuleKey;
  31. import org.sonar.api.rules.RuleType;
  32. import org.sonar.api.utils.System2;
  33. import org.sonar.db.DbTester;
  34. import org.sonar.db.RowNotFoundException;
  35. import org.sonar.db.component.BranchType;
  36. import org.sonar.db.component.ComponentDto;
  37. import org.sonar.db.component.ComponentTesting;
  38. import org.sonar.db.component.ComponentUpdateDto;
  39. import org.sonar.db.rule.RuleDefinitionDto;
  40. import org.sonar.db.rule.RuleDto;
  41. import org.sonar.db.rule.RuleTesting;
  42. import static java.util.Arrays.asList;
  43. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  44. import static org.apache.commons.lang.math.RandomUtils.nextInt;
  45. import static org.assertj.core.api.Assertions.assertThat;
  46. import static org.junit.rules.ExpectedException.none;
  47. import static org.sonar.db.component.ComponentTesting.newDirectory;
  48. import static org.sonar.db.component.ComponentTesting.newFileDto;
  49. import static org.sonar.db.component.ComponentTesting.newModuleDto;
  50. public class IssueDaoTest {
  51. private static final String PROJECT_UUID = "prj_uuid";
  52. private static final String PROJECT_KEY = "prj_key";
  53. private static final String FILE_UUID = "file_uuid";
  54. private static final String FILE_KEY = "file_key";
  55. private static final RuleDto RULE = RuleTesting.newXooX1();
  56. private static final String ISSUE_KEY1 = "I1";
  57. private static final String ISSUE_KEY2 = "I2";
  58. private static final RuleType[] RULE_TYPES_EXCEPT_HOTSPOT = Stream.of(RuleType.values())
  59. .filter(r -> r != RuleType.SECURITY_HOTSPOT)
  60. .toArray(RuleType[]::new);
  61. @Rule
  62. public ExpectedException expectedException = none();
  63. @Rule
  64. public DbTester db = DbTester.create(System2.INSTANCE);
  65. private IssueDao underTest = db.getDbClient().issueDao();
  66. @Test
  67. public void selectByKeyOrFail() {
  68. prepareTables();
  69. IssueDto issue = underTest.selectOrFailByKey(db.getSession(), ISSUE_KEY1);
  70. assertThat(issue.getKee()).isEqualTo(ISSUE_KEY1);
  71. assertThat(issue.getComponentUuid()).isEqualTo(FILE_UUID);
  72. assertThat(issue.getProjectUuid()).isEqualTo(PROJECT_UUID);
  73. assertThat(issue.getRuleUuid()).isEqualTo(RULE.getUuid());
  74. assertThat(issue.getLanguage()).isEqualTo(RULE.getLanguage());
  75. assertThat(issue.getSeverity()).isEqualTo("BLOCKER");
  76. assertThat(issue.getType()).isEqualTo(2);
  77. assertThat(issue.isManualSeverity()).isFalse();
  78. assertThat(issue.getMessage()).isEqualTo("the message");
  79. assertThat(issue.getLine()).isEqualTo(500);
  80. assertThat(issue.getEffort()).isEqualTo(10L);
  81. assertThat(issue.getGap()).isEqualTo(3.14);
  82. assertThat(issue.getStatus()).isEqualTo("RESOLVED");
  83. assertThat(issue.getResolution()).isEqualTo("FIXED");
  84. assertThat(issue.getChecksum()).isEqualTo("123456789");
  85. assertThat(issue.getAuthorLogin()).isEqualTo("morgan");
  86. assertThat(issue.getAssigneeUuid()).isEqualTo("karadoc");
  87. assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
  88. assertThat(issue.getIssueCreationDate()).isNotNull();
  89. assertThat(issue.getIssueUpdateDate()).isNotNull();
  90. assertThat(issue.getIssueCloseDate()).isNotNull();
  91. assertThat(issue.getCreatedAt()).isEqualTo(1_440_000_000_000L);
  92. assertThat(issue.getUpdatedAt()).isEqualTo(1_440_000_000_000L);
  93. assertThat(issue.getRuleRepo()).isEqualTo(RULE.getRepositoryKey());
  94. assertThat(issue.getRule()).isEqualTo(RULE.getRuleKey());
  95. assertThat(issue.getComponentKey()).isEqualTo(FILE_KEY);
  96. assertThat(issue.getProjectKey()).isEqualTo(PROJECT_KEY);
  97. assertThat(issue.getLocations()).isNull();
  98. assertThat(issue.parseLocations()).isNull();
  99. assertThat(issue.isExternal()).isTrue();
  100. }
  101. @Test
  102. public void selectByKeyOrFail_fails_if_key_not_found() {
  103. expectedException.expect(RowNotFoundException.class);
  104. expectedException.expectMessage("Issue with key 'DOES_NOT_EXIST' does not exist");
  105. prepareTables();
  106. underTest.selectOrFailByKey(db.getSession(), "DOES_NOT_EXIST");
  107. }
  108. @Test
  109. public void selectByKeys() {
  110. // contains I1 and I2
  111. prepareTables();
  112. List<IssueDto> issues = underTest.selectByKeys(db.getSession(), asList("I1", "I2", "I3"));
  113. // results are not ordered, so do not use "containsExactly"
  114. assertThat(issues).extracting("key").containsOnly("I1", "I2");
  115. }
  116. @Test
  117. public void scrollNonClosedByComponentUuid() {
  118. RuleDefinitionDto rule = db.rules().insert();
  119. ComponentDto project = db.components().insertPrivateProject();
  120. ComponentDto file = db.components().insertComponent(newFileDto(project));
  121. IssueDto openIssue1OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  122. IssueDto openIssue2OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  123. IssueDto closedIssueOnFile = db.issues().insert(rule, project, file, i -> i.setStatus("CLOSED").setResolution("FIXED").setType(randomRuleTypeExceptHotspot()));
  124. IssueDto openIssueOnProject = db.issues().insert(rule, project, project, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  125. IssueDto securityHotspot = db.issues().insert(rule, project, file, i -> i.setType(RuleType.SECURITY_HOTSPOT));
  126. RuleDefinitionDto external = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto.setIsExternal(true));
  127. IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL").setType(randomRuleTypeExceptHotspot()));
  128. assertThat(underTest.selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(db.getSession(), file.uuid()))
  129. .extracting(IssueDto::getKey)
  130. .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile}).map(IssueDto::getKey).toArray(String[]::new));
  131. assertThat(underTest.selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(db.getSession(), project.uuid()))
  132. .extracting(IssueDto::getKey)
  133. .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssueOnProject}).map(IssueDto::getKey).toArray(String[]::new));
  134. assertThat(underTest.selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(db.getSession(), "does_not_exist")).isEmpty();
  135. }
  136. @Test
  137. public void scrollNonClosedByModuleOrProject() {
  138. RuleDefinitionDto rule = db.rules().insert();
  139. ComponentDto project = db.components().insertPrivateProject();
  140. ComponentDto anotherProject = db.components().insertPrivateProject();
  141. ComponentDto module = db.components().insertComponent(newModuleDto(project));
  142. ComponentDto file = db.components().insertComponent(newFileDto(module));
  143. IssueDto openIssue1OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  144. IssueDto openIssue2OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  145. IssueDto closedIssueOnFile = db.issues().insert(rule, project, file, i -> i.setStatus("CLOSED").setResolution("FIXED").setType(randomRuleTypeExceptHotspot()));
  146. IssueDto openIssueOnModule = db.issues().insert(rule, project, module, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  147. IssueDto openIssueOnProject = db.issues().insert(rule, project, project, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  148. IssueDto openIssueOnAnotherProject = db.issues().insert(rule, anotherProject, anotherProject,
  149. i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
  150. IssueDto securityHotspot = db.issues().insert(rule, project, file, i -> i.setType(RuleType.SECURITY_HOTSPOT));
  151. RuleDefinitionDto external = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto.setIsExternal(true));
  152. IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL").setType(randomRuleTypeExceptHotspot()));
  153. assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(db.getSession(), project))
  154. .extracting(IssueDto::getKey)
  155. .containsExactlyInAnyOrder(
  156. Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile, openIssueOnModule, openIssueOnProject}).map(IssueDto::getKey).toArray(String[]::new));
  157. assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(db.getSession(), module))
  158. .extracting(IssueDto::getKey)
  159. .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile, openIssueOnModule}).map(IssueDto::getKey).toArray(String[]::new));
  160. ComponentDto notPersisted = ComponentTesting.newPrivateProjectDto();
  161. assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(db.getSession(), notPersisted)).isEmpty();
  162. }
  163. @Test
  164. public void selectOpenByComponentUuid() {
  165. RuleDefinitionDto rule = db.rules().insert();
  166. ComponentDto project = db.components().insertPublicProject();
  167. ComponentDto projectBranch = db.components().insertProjectBranch(project,
  168. b -> b.setKey("feature/foo")
  169. .setBranchType(BranchType.BRANCH));
  170. ComponentDto file = db.components().insertComponent(newFileDto(projectBranch));
  171. IssueDto openIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_OPEN).setResolution(null));
  172. IssueDto closedIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_FIXED));
  173. IssueDto reopenedIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_REOPENED).setResolution(null));
  174. IssueDto confirmedIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_CONFIRMED).setResolution(null));
  175. IssueDto wontfixIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_WONT_FIX));
  176. IssueDto fpIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_FALSE_POSITIVE));
  177. assertThat(underTest.selectOpenByComponentUuids(db.getSession(), Collections.singletonList(file.uuid())))
  178. .extracting("kee")
  179. .containsOnly(openIssue.getKey(), reopenedIssue.getKey(), confirmedIssue.getKey(), wontfixIssue.getKey(), fpIssue.getKey());
  180. }
  181. @Test
  182. public void selectOpenByComponentUuid_should_correctly_map_required_fields() {
  183. RuleDefinitionDto rule = db.rules().insert();
  184. ComponentDto project = db.components().insertPublicProject();
  185. ComponentDto projectBranch = db.components().insertProjectBranch(project,
  186. b -> b.setKey("feature/foo")
  187. .setBranchType(BranchType.BRANCH));
  188. ComponentDto file = db.components().insertComponent(newFileDto(projectBranch));
  189. IssueDto fpIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus("RESOLVED").setResolution("FALSE-POSITIVE"));
  190. PrIssueDto fp = underTest.selectOpenByComponentUuids(db.getSession(), Collections.singletonList(file.uuid())).get(0);
  191. assertThat(fp.getLine()).isEqualTo(fpIssue.getLine());
  192. assertThat(fp.getMessage()).isEqualTo(fpIssue.getMessage());
  193. assertThat(fp.getChecksum()).isEqualTo(fpIssue.getChecksum());
  194. assertThat(fp.getRuleKey()).isEqualTo(fpIssue.getRuleKey());
  195. assertThat(fp.getStatus()).isEqualTo(fpIssue.getStatus());
  196. assertThat(fp.getLine()).isNotNull();
  197. assertThat(fp.getLine()).isNotZero();
  198. assertThat(fp.getMessage()).isNotNull();
  199. assertThat(fp.getChecksum()).isNotNull();
  200. assertThat(fp.getChecksum()).isNotEmpty();
  201. assertThat(fp.getRuleKey()).isNotNull();
  202. assertThat(fp.getStatus()).isNotNull();
  203. assertThat(fp.getBranchKey()).isEqualTo("feature/foo");
  204. assertThat(fp.getIssueUpdateDate()).isNotNull();
  205. }
  206. @Test
  207. public void test_selectGroupsOfComponentTreeOnLeak_on_component_without_issues() {
  208. ComponentDto project = db.components().insertPublicProject();
  209. ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project));
  210. Collection<IssueGroupDto> groups = underTest.selectIssueGroupsByBaseComponent(db.getSession(), file, 1_000L);
  211. assertThat(groups).isEmpty();
  212. }
  213. @Test
  214. public void selectGroupsOfComponentTreeOnLeak_on_file() {
  215. ComponentDto project = db.components().insertPublicProject();
  216. ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project));
  217. RuleDefinitionDto rule = db.rules().insert();
  218. IssueDto fpBug = db.issues().insert(rule, project, file,
  219. i -> i.setStatus("RESOLVED").setResolution("FALSE-POSITIVE").setSeverity("MAJOR").setType(RuleType.BUG).setIssueCreationTime(1_500L));
  220. IssueDto criticalBug1 = db.issues().insert(rule, project, file,
  221. i -> i.setStatus("OPEN").setResolution(null).setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_600L));
  222. IssueDto criticalBug2 = db.issues().insert(rule, project, file,
  223. i -> i.setStatus("OPEN").setResolution(null).setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_700L));
  224. // closed issues are ignored
  225. IssueDto closed = db.issues().insert(rule, project, file,
  226. i -> i.setStatus("CLOSED").setResolution("REMOVED").setSeverity("CRITICAL").setType(RuleType.BUG).setIssueCreationTime(1_700L));
  227. Collection<IssueGroupDto> result = underTest.selectIssueGroupsByBaseComponent(db.getSession(), file, 1_000L);
  228. assertThat(result.stream().mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
  229. assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.BUG.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
  230. assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.CODE_SMELL.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isZero();
  231. assertThat(result.stream().filter(g -> g.getRuleType() == RuleType.VULNERABILITY.getDbConstant()).mapToLong(IssueGroupDto::getCount).sum()).isZero();
  232. assertThat(result.stream().filter(g -> g.getSeverity().equals("CRITICAL")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
  233. assertThat(result.stream().filter(g -> g.getSeverity().equals("MAJOR")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(1);
  234. assertThat(result.stream().filter(g -> g.getSeverity().equals("MINOR")).mapToLong(IssueGroupDto::getCount).sum()).isZero();
  235. assertThat(result.stream().filter(g -> g.getStatus().equals("OPEN")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
  236. assertThat(result.stream().filter(g -> g.getStatus().equals("RESOLVED")).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(1);
  237. assertThat(result.stream().filter(g -> g.getStatus().equals("CLOSED")).mapToLong(IssueGroupDto::getCount).sum()).isZero();
  238. assertThat(result.stream().filter(g -> "FALSE-POSITIVE".equals(g.getResolution())).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(1);
  239. assertThat(result.stream().filter(g -> g.getResolution() == null).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(2);
  240. assertThat(result.stream().filter(g -> g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
  241. assertThat(result.stream().filter(g -> !g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isZero();
  242. // test leak
  243. result = underTest.selectIssueGroupsByBaseComponent(db.getSession(), file, 999_999_999L);
  244. assertThat(result.stream().filter(g -> g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isZero();
  245. assertThat(result.stream().filter(g -> !g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
  246. // test leak using exact creation time of criticalBug2 issue
  247. result = underTest.selectIssueGroupsByBaseComponent(db.getSession(), file, criticalBug2.getIssueCreationTime());
  248. assertThat(result.stream().filter(g -> g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isZero();
  249. assertThat(result.stream().filter(g -> !g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isEqualTo(3);
  250. }
  251. @Test
  252. public void selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid() {
  253. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), randomAlphabetic(12)))
  254. .isEmpty();
  255. ComponentDto project1 = db.components().insertPrivateProject();
  256. ComponentDto module11 = db.components().insertComponent(newModuleDto(project1));
  257. ComponentDto dir11 = db.components().insertComponent(newDirectory(module11, randomAlphabetic(10)));
  258. ComponentDto dir12 = db.components().insertComponent(newDirectory(module11, randomAlphabetic(11)));
  259. ComponentDto module12 = db.components().insertComponent(newModuleDto(project1));
  260. ComponentDto dir13 = db.components().insertComponent(newDirectory(module12, randomAlphabetic(12)));
  261. ComponentDto dir14 = db.components().insertComponent(newDirectory(project1, randomAlphabetic(13)));
  262. ComponentDto file11 = db.components().insertComponent(newFileDto(project1));
  263. ComponentDto application = db.components().insertPrivateApplication();
  264. ComponentDto view = db.components().insertPublicPortfolio();
  265. ComponentDto subview = db.components().insertSubView(view);
  266. ComponentDto project2 = db.components().insertPublicProject();
  267. ComponentDto module21 = db.components().insertComponent(newModuleDto(project2));
  268. ComponentDto dir21 = db.components().insertComponent(newDirectory(project2, randomAlphabetic(15)));
  269. ComponentDto file21 = db.components().insertComponent(newFileDto(project2));
  270. List<ComponentDto> allcomponents = asList(project1, module11, dir11, dir12, module12, dir13, dir14, file11, application, view, subview, project2, module21, dir21, file21);
  271. List<ComponentDto> allModuleOrDirs = asList(module11, dir11, dir12, module12, dir13, dir14, module21, dir21);
  272. // no issues => always empty
  273. allcomponents.stream()
  274. .map(ComponentDto::uuid)
  275. .forEach(uuid -> assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), uuid))
  276. .isEmpty());
  277. // return module or dir only if has issue with status different from CLOSED
  278. allModuleOrDirs
  279. .forEach(moduleOrDir -> {
  280. String projectUuid = moduleOrDir.projectUuid();
  281. // CLOSED issue => not returned
  282. db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(moduleOrDir).setStatus(Issue.STATUS_CLOSED));
  283. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
  284. .isEmpty();
  285. // status != CLOSED => returned
  286. Issue.STATUSES.stream()
  287. .filter(t -> !Issue.STATUS_CLOSED.equals(t))
  288. .forEach(status -> {
  289. IssueDto issue = db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(moduleOrDir).setStatus(status));
  290. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
  291. .containsOnly(moduleOrDir.uuid());
  292. db.executeDdl("delete from issues where kee='" + issue.getKey() + "'");
  293. db.commit();
  294. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
  295. .isEmpty();
  296. });
  297. });
  298. // never return project, view, subview, app or file, whatever the issue status
  299. Stream.of(project1, file11, application, view, subview, project2, file21)
  300. .forEach(neitherModuleNorDir -> {
  301. String projectUuid = neitherModuleNorDir.projectUuid();
  302. Issue.STATUSES
  303. .forEach(status -> {
  304. db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(neitherModuleNorDir).setStatus(status));
  305. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
  306. .isEmpty();
  307. });
  308. });
  309. // never return whatever the component if it is disabled
  310. allcomponents
  311. .forEach(component -> {
  312. String projectUuid = component.projectUuid();
  313. // issues for each status => returned if component is dir or module
  314. Issue.STATUSES
  315. .forEach(status -> db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(component).setStatus(status)));
  316. if (allModuleOrDirs.contains(component)) {
  317. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
  318. .containsOnly(component.uuid());
  319. } else {
  320. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
  321. .isEmpty();
  322. }
  323. // disable component and test again => not returned anymore
  324. db.getDbClient().componentDao().update(db.getSession(), ComponentUpdateDto.copyFrom(component).setBEnabled(false).setBChanged(true));
  325. db.getDbClient().componentDao().applyBChangesForRootComponentUuid(db.getSession(), projectUuid);
  326. db.commit();
  327. assertThat(db.getDbClient().componentDao().selectByUuid(db.getSession(), component.uuid()).get().isEnabled())
  328. .isFalse();
  329. assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
  330. .isEmpty();
  331. });
  332. }
  333. private static IssueDto newIssueDto(String key) {
  334. IssueDto dto = new IssueDto();
  335. dto.setComponent(new ComponentDto().setDbKey("struts:Action").setUuid("component-uuid"));
  336. dto.setProject(new ComponentDto().setDbKey("struts").setUuid("project-uuid"));
  337. dto.setRule(RuleTesting.newRule(RuleKey.of("squid", "S001")).setUuid("uuid-200"));
  338. dto.setKee(key);
  339. dto.setType(2);
  340. dto.setLine(500);
  341. dto.setGap(3.14);
  342. dto.setEffort(10L);
  343. dto.setResolution("FIXED");
  344. dto.setStatus("RESOLVED");
  345. dto.setSeverity("BLOCKER");
  346. dto.setAuthorLogin("morgan");
  347. dto.setAssigneeUuid("karadoc");
  348. dto.setIssueAttributes("JIRA=FOO-1234");
  349. dto.setChecksum("123456789");
  350. dto.setMessage("the message");
  351. dto.setCreatedAt(1_440_000_000_000L);
  352. dto.setUpdatedAt(1_440_000_000_000L);
  353. dto.setIssueCreationTime(1_450_000_000_000L);
  354. dto.setIssueUpdateTime(1_450_000_000_000L);
  355. dto.setIssueCloseTime(1_450_000_000_000L);
  356. return dto;
  357. }
  358. private void prepareTables() {
  359. db.rules().insertRule(RULE.setIsExternal(true));
  360. ComponentDto projectDto = db.components().insertPrivateProject(t -> t.setUuid(PROJECT_UUID).setDbKey(PROJECT_KEY));
  361. db.components().insertComponent(newFileDto(projectDto).setUuid(FILE_UUID).setDbKey(FILE_KEY));
  362. underTest.insert(db.getSession(), newIssueDto(ISSUE_KEY1)
  363. .setMessage("the message")
  364. .setRuleUuid(RULE.getUuid())
  365. .setComponentUuid(FILE_UUID)
  366. .setProjectUuid(PROJECT_UUID));
  367. underTest.insert(db.getSession(), newIssueDto(ISSUE_KEY2)
  368. .setRuleUuid(RULE.getUuid())
  369. .setComponentUuid(FILE_UUID)
  370. .setProjectUuid(PROJECT_UUID));
  371. db.getSession().commit();
  372. }
  373. private static RuleType randomRuleTypeExceptHotspot() {
  374. return RULE_TYPES_EXCEPT_HOTSPOT[nextInt(RULE_TYPES_EXCEPT_HOTSPOT.length)];
  375. }
  376. }