diff options
author | Léo Geoffroy <leo.geoffroy@sonarsource.com> | 2023-11-03 11:34:54 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-11-08 20:02:53 +0000 |
commit | c8d1b7eb2494d92f20fb8b498efdbb2e3f8ea12c (patch) | |
tree | eee5a1806103bdc81e5e8792e433580a9a1efa03 | |
parent | 0ea63b469a06ae68a712c593e06de52c6b80540c (diff) | |
download | sonarqube-c8d1b7eb2494d92f20fb8b498efdbb2e3f8ea12c.tar.gz sonarqube-c8d1b7eb2494d92f20fb8b498efdbb2e3f8ea12c.zip |
SONAR-20870 Add accept transition in replacement of wontfix
13 files changed, 122 insertions, 54 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TransitionIssuesToAnticipatedStatesVisitorTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TransitionIssuesToAnticipatedStatesVisitorTest.java index f7eace23e23..a053ee0dfc5 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TransitionIssuesToAnticipatedStatesVisitorTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TransitionIssuesToAnticipatedStatesVisitorTest.java @@ -26,6 +26,7 @@ import java.util.stream.Stream; import org.junit.Rule; import org.junit.Test; import org.slf4j.event.Level; +import org.sonar.api.issue.DefaultTransitions; import org.sonar.api.rule.RuleKey; import org.sonar.api.testfixtures.log.LogTester; import org.sonar.ce.task.log.CeTaskMessages; @@ -72,7 +73,7 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest { assertThat(issue.isBeingClosed()).isTrue(); assertThat(issue.getAnticipatedTransitionUuid()).isPresent(); - verify(issueLifecycle).doManualTransition(issue, "wontfix", "admin"); + verify(issueLifecycle).doManualTransition(issue, DefaultTransitions.ACCEPT, "admin"); verify(issueLifecycle).addComment(issue, "doing the transition in an anticipated way", "admin"); } @@ -91,7 +92,7 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest { assertThat(issue.isBeingClosed()).isFalse(); assertThat(issue.getAnticipatedTransitionUuid()).isEmpty(); - verify(issueLifecycle).doManualTransition(issue, "wontfix", "admin"); + verify(issueLifecycle).doManualTransition(issue, DefaultTransitions.ACCEPT, "admin"); verifyNoMoreInteractions(issueLifecycle); assertThat(logTester.logs(Level.WARN)) .contains(String.format("Cannot resolve issue at line %s of %s due to: %s", issue.getLine(), issue.componentKey(), exceptionMessage)); @@ -157,7 +158,7 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest { assertThat(issue.isBeingClosed()).isTrue(); assertThat(issue.getAnticipatedTransitionUuid()).isPresent(); - verify(issueLifecycle).doManualTransition(issue, "wontfix", "admin"); + verify(issueLifecycle).doManualTransition(issue, DefaultTransitions.ACCEPT, "admin"); verify(issueLifecycle).addComment(issue, "Automatically transitioned from SonarLint", "admin"); } @@ -182,11 +183,11 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest { } private Collection<AnticipatedTransition> getAnticipatedTransitions(String projecKey, String fileName) { - return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1, "abcdefghi", "wontfix", "doing the transition in an anticipated way")).collect(Collectors.toList()); + return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1, "abcdefghi", DefaultTransitions.ACCEPT, "doing the transition in an anticipated way")).collect(Collectors.toList()); } private Collection<AnticipatedTransition> getAnticipatedTransitionsWithEmptyComment(String projecKey, String fileName) { - return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1, "abcdefghi", "wontfix", null)).collect(Collectors.toList()); + return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1, "abcdefghi", DefaultTransitions.ACCEPT, null)).collect(Collectors.toList()); } private Component getComponent(Component.Type type) { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java index 4b0d9f186f7..01e41175b76 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java @@ -75,35 +75,43 @@ public class IssueWorkflow implements Startable { private static void buildManualTransitions(StateMachine.Builder builder) { builder - // confirm - .transition(Transition.builder(DefaultTransitions.CONFIRM) - .from(STATUS_OPEN).to(STATUS_CONFIRMED) + //replacement transition for org.sonar.api.issue.DefaultTransitions.WONT_FIX + .transition(Transition.builder(DefaultTransitions.ACCEPT) + .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(null)) + .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) + .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) - .transition(Transition.builder(DefaultTransitions.CONFIRM) - .from(STATUS_REOPENED).to(STATUS_CONFIRMED) + .transition(Transition.builder(DefaultTransitions.ACCEPT) + .from(STATUS_REOPENED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(null)) + .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) + .requiredProjectPermission(UserRole.ISSUE_ADMIN) + .build()) + .transition(Transition.builder(DefaultTransitions.ACCEPT) + .from(STATUS_CONFIRMED).to(STATUS_RESOLVED) + .conditions(IsNotHotspot.INSTANCE) + .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) + .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) - // resolve as fixed - .transition(Transition.builder(DefaultTransitions.RESOLVE) + // resolve as false-positive + .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(RESOLUTION_FIXED)) + .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) - .transition(Transition.builder(DefaultTransitions.RESOLVE) + .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) .from(STATUS_REOPENED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(RESOLUTION_FIXED)) + .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) - .transition(Transition.builder(DefaultTransitions.RESOLVE) + .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) .from(STATUS_CONFIRMED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(RESOLUTION_FIXED)) + .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) @@ -119,27 +127,39 @@ public class IssueWorkflow implements Startable { .functions(new SetResolution(null)) .build()) - // resolve as false-positive - .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) + // confirm + .transition(Transition.builder(DefaultTransitions.CONFIRM) + .from(STATUS_OPEN).to(STATUS_CONFIRMED) + .conditions(IsNotHotspot.INSTANCE) + .functions(new SetResolution(null)) + .build()) + .transition(Transition.builder(DefaultTransitions.CONFIRM) + .from(STATUS_REOPENED).to(STATUS_CONFIRMED) + .conditions(IsNotHotspot.INSTANCE) + .functions(new SetResolution(null)) + .build()) + + // resolve as fixed + .transition(Transition.builder(DefaultTransitions.RESOLVE) .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) + .functions(new SetResolution(RESOLUTION_FIXED)) .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) - .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) + .transition(Transition.builder(DefaultTransitions.RESOLVE) .from(STATUS_REOPENED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) + .functions(new SetResolution(RESOLUTION_FIXED)) .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) - .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) + .transition(Transition.builder(DefaultTransitions.RESOLVE) .from(STATUS_CONFIRMED).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) - .functions(new SetResolution(RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE) + .functions(new SetResolution(RESOLUTION_FIXED)) .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()) - // resolve as won't fix + // resolve as won't fix, deprecated .transition(Transition.builder(DefaultTransitions.WONT_FIX) .from(STATUS_OPEN).to(STATUS_RESOLVED) .conditions(IsNotHotspot.INSTANCE) @@ -158,6 +178,7 @@ public class IssueWorkflow implements Startable { .functions(new SetResolution(RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE) .requiredProjectPermission(UserRole.ISSUE_ADMIN) .build()); + } private static void buildSecurityHotspotTransitions(StateMachine.Builder builder) { diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java index debdd09d37a..b1fe32a6693 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java @@ -85,7 +85,7 @@ public class IssueWorkflowTest { DefaultIssue issue = new DefaultIssue().setStatus(STATUS_OPEN); List<Transition> transitions = underTest.outTransitions(issue); - assertThat(keys(transitions)).containsOnly("confirm", "falsepositive", "resolve", "wontfix"); + assertThat(keys(transitions)).containsOnly("confirm", "falsepositive", "resolve", "wontfix", "accept"); } @Test @@ -94,7 +94,7 @@ public class IssueWorkflowTest { DefaultIssue issue = new DefaultIssue().setStatus(STATUS_CONFIRMED); List<Transition> transitions = underTest.outTransitions(issue); - assertThat(keys(transitions)).containsOnly("unconfirm", "falsepositive", "resolve", "wontfix"); + assertThat(keys(transitions)).containsOnly("unconfirm", "falsepositive", "resolve", "wontfix", "accept"); } @Test @@ -112,7 +112,7 @@ public class IssueWorkflowTest { DefaultIssue issue = new DefaultIssue().setStatus(STATUS_REOPENED); List<Transition> transitions = underTest.outTransitions(issue); - assertThat(keys(transitions)).containsOnly("confirm", "resolve", "falsepositive", "wontfix"); + assertThat(keys(transitions)).containsOnly("confirm", "resolve", "falsepositive", "wontfix", "accept"); } @Test @@ -429,6 +429,25 @@ public class IssueWorkflowTest { assertThat(issue.assignee()).isNull(); } + @Test + public void doManualTransition_shouldTransitionToResolutionWontFix_whenAccepted() { + DefaultIssue issue = new DefaultIssue() + .setKey("ABCDE") + .setStatus(STATUS_OPEN) + .setRuleKey(RuleKey.of("java", "AvoidCycle")) + .setAssigneeUuid("morgan"); + + underTest.start(); + underTest.doManualTransition(issue, DefaultTransitions.ACCEPT, issueChangeContextByScanBuilder(new Date()).build()); + + assertThat(issue.resolution()).isEqualTo(RESOLUTION_WONT_FIX); + assertThat(issue.status()).isEqualTo(STATUS_RESOLVED); + + // should remove assignee + assertThat(issue.assignee()).isNull(); + } + + private static DefaultIssue newClosedIssue(String resolution) { return new DefaultIssue() .setKey("ABCDE") diff --git a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImpl.java b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImpl.java index eade0b95a1d..1111c5ed4eb 100644 --- a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImpl.java +++ b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImpl.java @@ -41,6 +41,7 @@ import org.sonar.db.pushevent.PushEventDto; import static java.nio.charset.StandardCharsets.UTF_8; import static org.elasticsearch.common.Strings.isNullOrEmpty; +import static org.sonar.api.issue.DefaultTransitions.ACCEPT; import static org.sonar.api.issue.DefaultTransitions.CONFIRM; import static org.sonar.api.issue.DefaultTransitions.FALSE_POSITIVE; import static org.sonar.api.issue.DefaultTransitions.UNCONFIRM; @@ -159,7 +160,7 @@ public class IssueChangeEventServiceImpl implements IssueChangeEventService { return null; } - return transitionOrStatus.equals(WONT_FIX) || transitionOrStatus.equals(FALSE_POSITIVE) || + return transitionOrStatus.equals(ACCEPT) || transitionOrStatus.equals(WONT_FIX) || transitionOrStatus.equals(FALSE_POSITIVE) || transitionOrStatus.equals(FALSE_POSITIVE_KEY) || transitionOrStatus.equals(WONT_FIX_KEY); } diff --git a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java index 7a528fee3db..db567f959f3 100644 --- a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java +++ b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/issues/IssueChangeEventServiceImplTest.java @@ -44,6 +44,7 @@ import org.sonarqube.ws.Common; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; +import static org.sonar.api.issue.DefaultTransitions.ACCEPT; import static org.sonar.api.issue.DefaultTransitions.CONFIRM; import static org.sonar.api.issue.DefaultTransitions.FALSE_POSITIVE; import static org.sonar.api.issue.DefaultTransitions.REOPEN; @@ -89,14 +90,15 @@ public class IssueChangeEventServiceImplTest { RuleDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, mainBranch, projectData.getMainBranchComponent(), i -> i.setSeverity(MAJOR.name())); - assertPushEventIsPersisted(project, mainBranch, issue, null, null, WONT_FIX, true, 1); - assertPushEventIsPersisted(project, mainBranch, issue, null, null, REOPEN, false, 2); - assertPushEventIsPersisted(project, mainBranch, issue, null, null, FALSE_POSITIVE, true, 3); - assertPushEventIsPersisted(project, mainBranch, issue, null, null, REOPEN, false, 4); - assertPushEventIsPersisted(project, mainBranch, issue, null, null, RESOLVE, false, 5); - assertPushEventIsPersisted(project, mainBranch, issue, null, null, REOPEN, false, 6); - assertNoIssueDistribution(project, mainBranch, issue, null, null, CONFIRM, 7); - assertNoIssueDistribution(project, mainBranch, issue, null, null, UNCONFIRM, 8); + assertPushEventIsPersisted(project, mainBranch, issue, null, null, ACCEPT, true, 1); + assertPushEventIsPersisted(project, mainBranch, issue, null, null, WONT_FIX, true, 2); + assertPushEventIsPersisted(project, mainBranch, issue, null, null, REOPEN, false, 3); + assertPushEventIsPersisted(project, mainBranch, issue, null, null, FALSE_POSITIVE, true, 4); + assertPushEventIsPersisted(project, mainBranch, issue, null, null, REOPEN, false, 5); + assertPushEventIsPersisted(project, mainBranch, issue, null, null, RESOLVE, false, 6); + assertPushEventIsPersisted(project, mainBranch, issue, null, null, REOPEN, false, 7); + assertNoIssueDistribution(project, mainBranch, issue, null, null, CONFIRM, 8); + assertNoIssueDistribution(project, mainBranch, issue, null, null, UNCONFIRM, 9); } @Test @@ -115,7 +117,7 @@ public class IssueChangeEventServiceImplTest { RuleDto rule = db.rules().insert(); IssueDto issue = db.issues().insert(rule, projectData.getMainBranchDto(), projectData.getMainBranchComponent(), i -> i.setSeverity(MAJOR.name())); - assertPushEventIsPersisted(projectData.getProjectDto(), projectData.getMainBranchDto(), issue, BLOCKER.name(), Common.RuleType.BUG.name(), WONT_FIX, true, 1); + assertPushEventIsPersisted(projectData.getProjectDto(), projectData.getMainBranchDto(), issue, BLOCKER.name(), Common.RuleType.BUG.name(), ACCEPT, true, 1); } @Test diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java index 444e934e1d6..7cd0791db28 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/TransitionServiceIT.java @@ -71,7 +71,7 @@ public class TransitionServiceIT { List<Transition> result = underTest.listTransitions(issue.toDefaultIssue()); - assertThat(result).extracting(Transition::key).containsOnly("confirm", "resolve", "falsepositive", "wontfix"); + assertThat(result).extracting(Transition::key).containsExactly("accept", "falsepositive", "confirm", "resolve", "wontfix"); } @Test @@ -85,7 +85,7 @@ public class TransitionServiceIT { List<Transition> result = underTest.listTransitions(externalIssue.toDefaultIssue()); - assertThat(result).extracting(Transition::key).containsOnly("confirm", "resolve", "falsepositive", "wontfix"); + assertThat(result).extracting(Transition::key).containsExactly("accept", "falsepositive", "confirm", "resolve", "wontfix"); } @Test diff --git a/server/sonar-webserver-webapi/src/it/resources/org/sonar/server/issue/ws/SearchActionIT/load_additional_fields_with_issue_admin_permission.json b/server/sonar-webserver-webapi/src/it/resources/org/sonar/server/issue/ws/SearchActionIT/load_additional_fields_with_issue_admin_permission.json index 7cdbead55f2..83074320245 100644 --- a/server/sonar-webserver-webapi/src/it/resources/org/sonar/server/issue/ws/SearchActionIT/load_additional_fields_with_issue_admin_permission.json +++ b/server/sonar-webserver-webapi/src/it/resources/org/sonar/server/issue/ws/SearchActionIT/load_additional_fields_with_issue_admin_permission.json @@ -11,9 +11,10 @@ "set_severity" ], "transitions": [ + "accept", + "falsepositive", "confirm", "resolve", - "falsepositive", "wontfix" ] } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java index e06368caf2f..3d077b3324e 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/BulkChangeAction.java @@ -80,10 +80,12 @@ import static java.util.Map.of; import static java.util.Objects.requireNonNull; import static java.util.function.Function.identity; import static java.util.stream.Collectors.toMap; +import static org.sonar.api.issue.DefaultTransitions.ACCEPT; import static org.sonar.api.issue.DefaultTransitions.OPEN_AS_VULNERABILITY; import static org.sonar.api.issue.DefaultTransitions.REOPEN; import static org.sonar.api.issue.DefaultTransitions.RESOLVE_AS_REVIEWED; import static org.sonar.api.issue.DefaultTransitions.SET_AS_IN_REVIEW; +import static org.sonar.api.issue.DefaultTransitions.WONT_FIX; import static org.sonar.api.rule.Severity.BLOCKER; import static org.sonar.api.rules.RuleType.BUG; import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; @@ -150,9 +152,11 @@ public class BulkChangeAction implements IssuesWsAction { "Requires authentication.") .setSince("3.7") .setChangelog( + new Change("10.4", "Transition '%s' is now deprecated. Use transition '%s' instead.".formatted(WONT_FIX, ACCEPT)), + new Change("10.4", "Transition '%s' is now supported.".formatted(ACCEPT)), new Change("10.2", format("Parameters '%s' and '%s' are now deprecated.", PARAM_SET_SEVERITY, PARAM_SET_TYPE)), new Change("8.2", "Security hotspots are no longer supported and will be ignored."), - new Change("8.2", format("transitions '%s', '%s' and '%s' are no more supported", SET_AS_IN_REVIEW, RESOLVE_AS_REVIEWED, OPEN_AS_VULNERABILITY)), + new Change("8.2", format("Transitions '%s', '%s' and '%s' are no more supported", SET_AS_IN_REVIEW, RESOLVE_AS_REVIEWED, OPEN_AS_VULNERABILITY)), new Change("6.3", "'actions' parameter is ignored")) .setHandler(this) .setResponseExample(getClass().getResource("bulk_change-example.json")) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java index c50bc4f4109..a98e38aa480 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java @@ -77,11 +77,15 @@ public class DoTransitionAction implements IssuesWsAction { @Override public void define(WebService.NewController controller) { WebService.NewAction action = controller.createAction(ACTION_DO_TRANSITION) - .setDescription("Do workflow transition on an issue. Requires authentication and Browse permission on project.<br/>" + - "The transitions '" + DefaultTransitions.WONT_FIX + "' and '" + DefaultTransitions.FALSE_POSITIVE + "' require the permission 'Administer Issues'.<br/>" + - "The transitions involving security hotspots require the permission 'Administer Security Hotspot'.") + .setDescription(""" + Do workflow transition on an issue. Requires authentication and Browse permission on project.<br/> + The transitions '%s', '%s' and '%s' require the permission 'Administer Issues'.<br/> + The transitions involving security hotspots require the permission 'Administer Security Hotspot'. + """.formatted(DefaultTransitions.ACCEPT, DefaultTransitions.WONT_FIX, DefaultTransitions.FALSE_POSITIVE)) .setSince("3.6") .setChangelog( + new Change("10.4", "The transition '%s' is deprecated. Please use '%s' instead.".formatted(DefaultTransitions.WONT_FIX, DefaultTransitions.ACCEPT)), + new Change("10.4", "Add transition '%s'.".formatted(DefaultTransitions.ACCEPT)), new Change("10.4", "The response fields 'status' and 'resolution' are deprecated. Please use 'issueStatus' instead."), new Change("10.4", "Add 'issueStatus' field to the response."), new Change("10.2", "Add 'impacts', 'cleanCodeAttribute', 'cleanCodeAttributeCategory' fields to the response"), diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java index e71a325dada..01b860853a8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -33,6 +33,7 @@ import javax.annotation.Nullable; import org.apache.lucene.search.TotalHits; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.search.SearchHit; +import org.sonar.api.issue.DefaultTransitions; import org.sonar.api.issue.impact.SoftwareQuality; import org.sonar.api.rule.Severity; import org.sonar.api.rules.CleanCodeAttributeCategory; @@ -207,6 +208,8 @@ public class SearchAction implements IssuesWsAction { + "<br/>When issue indexation is in progress returns 503 service unavailable HTTP code.") .setSince("3.6") .setChangelog( + new Change("10.4", "Value '%s' for 'transition' response field is deprecated, use '%s' instead".formatted(DefaultTransitions.WONT_FIX, DefaultTransitions.ACCEPT)), + new Change("10.4", "Possible value '%s' for 'transition' response field has been added".formatted(DefaultTransitions.ACCEPT)), new Change("10.4", format(NEW_PARAM_ADDED_MESSAGE, PARAM_ISSUE_STATUSES)), new Change("10.4", format("Parameters '%s' and '%s' are deprecated in favor of '%s'.", PARAM_RESOLUTIONS, PARAM_STATUSES, PARAM_ISSUE_STATUSES)), new Change("10.4", format("Parameter '%s' is deprecated.", PARAM_SEVERITIES)), diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParser.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParser.java index 754b370fc73..f892415c90a 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParser.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParser.java @@ -21,17 +21,21 @@ package org.sonar.server.issue.ws.anticipatedtransition; import com.google.gson.Gson; import java.util.Arrays; +import java.util.Collection; import java.util.List; -import java.util.Set; +import java.util.stream.Collectors; import org.sonar.api.rule.RuleKey; import org.sonar.core.issue.AnticipatedTransition; +import static org.sonar.api.issue.DefaultTransitions.ACCEPT; +import static org.sonar.api.issue.DefaultTransitions.FALSE_POSITIVE; +import static org.sonar.api.issue.DefaultTransitions.WONT_FIX; + public class AnticipatedTransitionParser { private static final Gson GSON = new Gson(); - private static final String WONTFIX = "wontfix"; - private static final String FALSEPOSITIVE = "falsepositive"; - private static final Set<String> ALLOWED_TRANSITIONS = Set.of(WONTFIX, FALSEPOSITIVE); - private static final String TRANSITION_NOT_SUPPORTED_ERROR_MESSAGE = "Transition '%s' not supported. Only 'wontfix' and 'falsepositive' are supported."; + private static final Collection<String> ALLOWED_TRANSITIONS = List.of(WONT_FIX, ACCEPT, FALSE_POSITIVE); + private static final String TRANSITION_NOT_SUPPORTED_ERROR_MESSAGE = "Transition '%s' not supported." + " Only %s are supported.".formatted(ALLOWED_TRANSITIONS.stream() + .map(s -> "'" + s + "'").collect(Collectors.joining(","))); public List<AnticipatedTransition> parse(String requestBody, String userUuid, String projectKey) { List<GsonAnticipatedTransition> anticipatedTransitions; diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsAction.java index 287f0abd740..6177c174df6 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionsAction.java @@ -20,6 +20,8 @@ package org.sonar.server.issue.ws.anticipatedtransition; import java.io.BufferedReader; +import org.sonar.api.issue.DefaultTransitions; +import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -43,7 +45,13 @@ public class AnticipatedTransitionsAction implements IssuesWsAction { @Override public void define(WebService.NewController controller) { - WebService.NewAction action = controller.createAction(IssuesWsParameters.ACTION_ANTICIPATED_TRANSITIONS).setDescription(""" + WebService.NewAction action = controller + .createAction(IssuesWsParameters.ACTION_ANTICIPATED_TRANSITIONS) + .setChangelog( + new Change("10.4", "Transition '%s' is now deprecated. Use '%s' instead.".formatted(DefaultTransitions.WONT_FIX, DefaultTransitions.ACCEPT)), + new Change("10.4", "Transition '%s' has been added.".formatted(DefaultTransitions.ACCEPT)) + ) + .setDescription(""" Receive a list of anticipated transitions that can be applied to not yet discovered issues on a specific project.<br> Requires the following permission: 'Administer Issues' on the specified project.<br> Only <code>falsepositive</code> and <code>wontfix</code> transitions are supported.<br> diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParserTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParserTest.java index 4b535916e85..24dde37496c 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParserTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/anticipatedtransition/AnticipatedTransitionParserTest.java @@ -94,7 +94,7 @@ public class AnticipatedTransitionParserTest { // when Assertions.assertThatThrownBy(() -> underTest.parse(requestBodyWithInvalidTransition, USER_UUID, PROJECT_KEY)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("Transition 'invalid-transition' not supported. Only 'wontfix' and 'falsepositive' are supported."); + .hasMessage("Transition 'invalid-transition' not supported. Only 'wontfix','accept','falsepositive' are supported."); } // Handwritten Anticipated Transitions that are expected from the request-with-transitions.json file |