@Test public void do_transition() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); DefaultIssue defaultIssue = issue.toDefaultIssue(); boolean result = underTest.doTransition(defaultIssue, IssueChangeContext.createUser(new Date(), "user_uuid"), "confirm"); assertThat(result).isTrue(); assertThat(defaultIssue.status()).isEqualTo(STATUS_CONFIRMED); }
@Test public void return_only_open_project_issues_if_no_modules_and_folders() { ComponentDto file = dbTester.components().insertComponent(newFileDto(rootProjectDto)); IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null)); IssueDto closedIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("CLOSED").setResolution("FIXED")); IssueDto openIssue1OnFile = dbTester.issues().insert(rule, rootProjectDto, file, i -> i.setStatus("OPEN").setResolution(null)); assertThat(underTest.loadIssues()).extracting(DefaultIssue::key).containsOnly(openIssueOnProject.getKey()); }
@Test public void prefer_resolved_issues() { db.issues().insertIssue(IssueTesting.newIssue(rule, branch1Dto, fileOnBranch1Dto).setKee("issue1").setStatus(Issue.STATUS_REOPENED).setLine(1).setChecksum("checksum")); db.issues().insertIssue(IssueTesting.newIssue(rule, branch2Dto, fileOnBranch2Dto).setKee("issue2").setStatus(Issue.STATUS_CONFIRMED).setLine(1).setChecksum("checksum")); db.issues().insertIssue(IssueTesting.newIssue(rule, branch3Dto, fileOnBranch3Dto).setKee("issue3").setStatus(Issue.STATUS_RESOLVED) .setResolution(Issue.RESOLUTION_FALSE_POSITIVE).setLine(1).setChecksum("checksum")); DefaultIssue newIssue = createIssue("newIssue", rule.getKey(), Issue.STATUS_OPEN, null, new Date()); copier.tryMerge(FILE_1, Collections.singleton(newIssue)); ArgumentCaptor<DefaultIssue> issueToMerge = ArgumentCaptor.forClass(DefaultIssue.class); verify(issueLifecycle).mergeConfirmedOrResolvedFromShortLivingBranch(eq(newIssue), issueToMerge.capture(), eq("myBranch3")); assertThat(issueToMerge.getValue().key()).isEqualTo("issue3"); }
@Test public void migrate_and_return_folder_issues_on_root_project() { when(reportModulesPath.get()).thenReturn(Collections.emptyMap()); ComponentDto folder = dbTester.components().insertComponent(newDirectory(rootProjectDto, "src")); ComponentDto file = dbTester.components().insertComponent(newFileDto(rootProjectDto)); IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null)); IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null)); IssueDto openIssue1OnFile = dbTester.issues().insert(rule, rootProjectDto, file, i -> i.setStatus("OPEN").setResolution(null)); assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage) .containsExactlyInAnyOrder( tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()), tuple(openIssueOnDir.getKey(), "[src] Issue on dir")); }
@Test public void do_transition() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn().addProjectPermission(USER, project, file); call(issue.getKey(), "confirm"); verify(responseWriter).write(eq(issue.getKey()), preloadedSearchResponseDataCaptor.capture(), any(Request.class), any(Response.class)); verifyContentOfPreloadedSearchResponseData(issue); IssueDto issueReloaded = db.getDbClient().issueDao().selectByKey(db.getSession(), issue.getKey()).get(); assertThat(issueReloaded.getStatus()).isEqualTo(STATUS_CONFIRMED); assertThat(issueChangePostProcessor.calledComponents()).containsExactlyInAnyOrder(file); }
@Test public void list_transitions_returns_nothing_when_not_logged() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); List<Transition> result = underTest.listTransitions(issue.toDefaultIssue()); assertThat(result).isEmpty(); }
@Test public void use_db_path_if_module_missing_in_report() { ComponentDto module = dbTester.components().insertComponent(newModuleDto(rootProjectDto).setPath("moduleAInDb")); when(reportModulesPath.get()).thenReturn(Collections.emptyMap()); ComponentDto folder = dbTester.components().insertComponent(newDirectory(module, "src")); IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null)); IssueDto openIssueOnModule = dbTester.issues().insert(rule, rootProjectDto, module, i -> i.setStatus("OPEN").setMessage("Issue on module").setResolution(null)); IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null)); assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage) .containsExactlyInAnyOrder( tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()), tuple(openIssueOnModule.getKey(), "[moduleAInDb] Issue on module"), tuple(openIssueOnDir.getKey(), "[moduleAInDb/src] Issue on dir")); }
@Test public void selectOpenByComponentUuid() { RuleDefinitionDto rule = db.rules().insert(); ComponentDto project = db.components().insertMainBranch(); ComponentDto projectBranch = db.components().insertProjectBranch(project, b -> b.setKey("feature/foo") .setBranchType(BranchType.SHORT)); ComponentDto file = db.components().insertComponent(newFileDto(projectBranch)); IssueDto openIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_OPEN).setResolution(null)); IssueDto closedIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_FIXED)); IssueDto reopenedIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_REOPENED).setResolution(null)); IssueDto confirmedIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_CONFIRMED).setResolution(null)); IssueDto wontfixIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_WONT_FIX)); IssueDto fpIssue = db.issues().insert(rule, projectBranch, file, i -> i.setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_FALSE_POSITIVE)); assertThat(underTest.selectOpenByComponentUuids(db.getSession(), Collections.singletonList(file.uuid()))) .extracting("kee") .containsOnly(openIssue.getKey(), reopenedIssue.getKey(), confirmedIssue.getKey(), wontfixIssue.getKey(), fpIssue.getKey()); }
@Test public void empty_path_if_module_missing_in_report_and_db_and_for_slash_folder () { ComponentDto module = dbTester.components().insertComponent(newModuleDto(rootProjectDto).setPath(null)); when(reportModulesPath.get()).thenReturn(Collections.emptyMap()); ComponentDto folder = dbTester.components().insertComponent(newDirectory(module, "/")); IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null)); IssueDto openIssueOnModule = dbTester.issues().insert(rule, rootProjectDto, module, i -> i.setStatus("OPEN").setMessage("Issue on module").setResolution(null)); IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null)); assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage) .containsExactlyInAnyOrder( tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()), tuple(openIssueOnModule.getKey(), "Issue on module"), tuple(openIssueOnDir.getKey(), "Issue on dir")); } }
@Test public void migrate_and_return_module_and_folder_issues_on_module() { ComponentDto module = dbTester.components().insertComponent(newModuleDto(rootProjectDto).setPath("moduleAInDb")); when(reportModulesPath.get()).thenReturn(ImmutableMap.of(module.getDbKey(), "moduleAInReport")); ComponentDto folder = dbTester.components().insertComponent(newDirectory(module, "src")); ComponentDto file = dbTester.components().insertComponent(newFileDto(module)); IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null)); IssueDto openIssueOnModule = dbTester.issues().insert(rule, rootProjectDto, module, i -> i.setStatus("OPEN").setMessage("Issue on module").setResolution(null)); IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null)); IssueDto openIssue1OnFile = dbTester.issues().insert(rule, rootProjectDto, file, i -> i.setStatus("OPEN").setResolution(null)); assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage) .containsExactlyInAnyOrder( tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()), tuple(openIssueOnModule.getKey(), "[moduleAInReport] Issue on module"), tuple(openIssueOnDir.getKey(), "[moduleAInReport/src] Issue on dir")); }
@Test public void list_transitions_returns_empty_list_on_external_issue() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto externalRule = db.rules().insert(r -> r.setIsExternal(true)); IssueDto externalIssue = db.issues().insert(externalRule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn().addProjectPermission(ISSUE_ADMIN, project); List<Transition> result = underTest.listTransitions(externalIssue.toDefaultIssue()); assertThat(result).isEmpty(); }
@Test public void list_transitions_returns_only_transitions_that_do_not_requires_issue_admin_permission() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn(); List<Transition> result = underTest.listTransitions(issue.toDefaultIssue()); assertThat(result).extracting(Transition::key).containsOnly("confirm", "resolve"); }
@Test public void do_transition_fail_on_external_issue() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto externalRule = db.rules().insert(r -> r.setIsExternal(true)); IssueDto externalIssue = db.issues().insert(externalRule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); DefaultIssue defaultIssue = externalIssue.toDefaultIssue(); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Transition is not allowed on issues imported from external rule engines"); underTest.doTransition(defaultIssue, IssueChangeContext.createUser(new Date(), "user_uuid"), "confirm"); } }
@Test public void list_transitions() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn().addProjectPermission(ISSUE_ADMIN, project); List<Transition> result = underTest.listTransitions(issue.toDefaultIssue()); assertThat(result).extracting(Transition::key).containsOnly("confirm", "resolve", "falsepositive", "wontfix"); }
@Test public void ignore_external_issue() { UserDto user = db.users().insertUser(); userSession.logIn(user); ComponentDto project = db.components().insertPrivateProject(); addUserProjectPermissions(user, project, USER, ISSUE_ADMIN); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, project, i -> i.setStatus(STATUS_OPEN).setResolution(null)); RuleDefinitionDto externalRule = db.rules().insert(r -> r.setIsExternal(true)); IssueDto externalIssue = db.issues().insert(externalRule, project, project, i -> i.setStatus(STATUS_OPEN).setResolution(null)); BulkChangeWsResponse response = call(builder() .setIssues(asList(issue.getKey(), externalIssue.getKey())) .setDoTransition("confirm") .build()); checkResponse(response, 2, 1, 1, 0); }
@Test public void fail_if_no_transition_param() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn().addProjectPermission(USER, project, file); expectedException.expect(IllegalArgumentException.class); call(issue.getKey(), null); }
@Test public void fail_if_not_enough_permission_to_access_issue() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn().addProjectPermission(CODEVIEWER, project, file); expectedException.expect(ForbiddenException.class); call(issue.getKey(), "confirm"); }
@Test public void fail_if_not_enough_permission_to_apply_transition() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn().addProjectPermission(USER, project, file); // False-positive transition is requiring issue admin permission expectedException.expect(ForbiddenException.class); call(issue.getKey(), "falsepositive"); }
@Test public void fail_when_only_comment_action() { UserDto user = db.users().insertUser(); userSession.logIn(user); ComponentDto project = db.components().insertPrivateProject(); addUserProjectPermissions(user, project, USER); RuleDefinitionDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, project, project, i -> i.setType(BUG) .setStatus(STATUS_OPEN).setResolution(null)); expectedException.expectMessage("At least one action must be provided"); expectedException.expect(IllegalArgumentException.class); call(builder() .setIssues(singletonList(issue.getKey())) .setComment("type was badly defined") .build()); }
@Test public void fail_if_external_issue() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); RuleDefinitionDto externalRule = db.rules().insert(r -> r.setIsExternal(true)); IssueDto externalIssue = db.issues().insert(externalRule, project, file, i -> i.setStatus(STATUS_OPEN).setResolution(null)); userSession.logIn().addProjectPermission(USER, project, file); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Transition is not allowed on issues imported from external rule engines"); call(externalIssue.getKey(), "confirm"); }