From 22804e92cf169785138b2d41828faaff7bb1dc64 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 23 May 2013 10:29:04 +0200 Subject: [PATCH] SONAR-4329 Create a new CONFIRMED status for Issues --- .../resources/org/sonar/l10n/core.properties | 3 ++ .../core/issue/workflow/IssueWorkflow.java | 26 ++++++++++-- .../issue/workflow/IssueWorkflowTest.java | 40 +++++++++++++++++-- .../sonar/api/issue/DefaultTransitions.java | 2 + .../main/java/org/sonar/api/issue/Issue.java | 1 + 5 files changed, 65 insertions(+), 7 deletions(-) diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties index 2dd46637bf9..bf69c17b99b 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -537,6 +537,8 @@ issue.comment.submit=Comment issue.comment.delete_confirm_title=Delete Comment issue.comment.delete_confirm_message=Do you want to delete this comment? issue.comment.delete_confirm_button=Delete +issue.transition.confirm=Confirm +issue.transition.unconfirm=Unconfirm issue.transition.resolve=Resolve issue.transition.falsepositive=False-Positive issue.transition.reopen=Reopen @@ -551,6 +553,7 @@ issue.plan_must_be_created_first=An action plan should be first created to plan issue.status.REOPENED=Reopened issue.status.RESOLVED=Resolved issue.status.OPEN=Open +issue.status.CONFIRMED=Confirmed issue.status.CLOSED=Closed issue.resolution.OPEN=Open issue.resolution.FALSE-POSITIVE=False-positive diff --git a/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java b/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java index 926b769bcb9..8d1b1ea539b 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java @@ -32,9 +32,9 @@ import java.util.List; public class IssueWorkflow implements BatchComponent, ServerComponent, Startable { - private StateMachine machine; private final FunctionExecutor functionExecutor; private final IssueUpdater updater; + private StateMachine machine; public IssueWorkflow(FunctionExecutor functionExecutor, IssueUpdater updater) { this.functionExecutor = functionExecutor; @@ -46,8 +46,20 @@ public class IssueWorkflow implements BatchComponent, ServerComponent, Startable machine = StateMachine.builder() // order is important for UI - .states(Issue.STATUS_OPEN, Issue.STATUS_REOPENED, Issue.STATUS_RESOLVED, Issue.STATUS_CLOSED) + .states(Issue.STATUS_OPEN, Issue.STATUS_CONFIRMED, Issue.STATUS_REOPENED, Issue.STATUS_RESOLVED, Issue.STATUS_CLOSED) + .transition(Transition.builder(DefaultTransitions.CONFIRM) + .from(Issue.STATUS_OPEN).to(Issue.STATUS_CONFIRMED) + .functions(new SetResolution(null)) + .build()) + .transition(Transition.builder(DefaultTransitions.CONFIRM) + .from(Issue.STATUS_REOPENED).to(Issue.STATUS_CONFIRMED) + .functions(new SetResolution(null)) + .build()) + .transition(Transition.builder(DefaultTransitions.UNCONFIRM) + .from(Issue.STATUS_CONFIRMED).to(Issue.STATUS_OPEN) + .functions(new SetResolution(null)) + .build()) .transition(Transition.builder(DefaultTransitions.RESOLVE) .from(Issue.STATUS_OPEN).to(Issue.STATUS_RESOLVED) .functions(new SetResolution(Issue.RESOLUTION_FIXED)) @@ -56,6 +68,10 @@ public class IssueWorkflow implements BatchComponent, ServerComponent, Startable .from(Issue.STATUS_REOPENED).to(Issue.STATUS_RESOLVED) .functions(new SetResolution(Issue.RESOLUTION_FIXED)) .build()) + .transition(Transition.builder(DefaultTransitions.RESOLVE) + .from(Issue.STATUS_CONFIRMED).to(Issue.STATUS_RESOLVED) + .functions(new SetResolution(Issue.RESOLUTION_FIXED)) + .build()) .transition(Transition.builder(DefaultTransitions.REOPEN) .from(Issue.STATUS_RESOLVED).to(Issue.STATUS_REOPENED) .functions(new SetResolution(null)) @@ -74,6 +90,11 @@ public class IssueWorkflow implements BatchComponent, ServerComponent, Startable .conditions(new IsManual(false)) .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE)) .build()) + .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE) + .from(Issue.STATUS_CONFIRMED).to(Issue.STATUS_RESOLVED) + .conditions(new IsManual(false)) + .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE)) + .build()) // automatic transitions @@ -125,7 +146,6 @@ public class IssueWorkflow implements BatchComponent, ServerComponent, Startable return machine.state(issue.status()).outManualTransitions(issue); } - public void doAutomaticTransition(DefaultIssue issue, IssueChangeContext issueChangeContext) { Transition transition = stateOf(issue).outAutomaticTransition(issue); if (transition != null) { diff --git a/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java b/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java index e4a24c24668..7919a92219c 100644 --- a/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java +++ b/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java @@ -28,6 +28,7 @@ import org.sonar.core.issue.IssueChangeContext; import org.sonar.core.issue.IssueUpdater; import javax.annotation.Nullable; + import java.util.Collection; import java.util.Date; import java.util.List; @@ -47,6 +48,7 @@ public class IssueWorkflowTest { workflow.start(); assertThat(workflow.machine()).isNotNull(); assertThat(workflow.machine().state(Issue.STATUS_OPEN)).isNotNull(); + assertThat(workflow.machine().state(Issue.STATUS_CONFIRMED)).isNotNull(); assertThat(workflow.machine().state(Issue.STATUS_CLOSED)).isNotNull(); assertThat(workflow.machine().state(Issue.STATUS_REOPENED)).isNotNull(); assertThat(workflow.machine().state(Issue.STATUS_RESOLVED)).isNotNull(); @@ -57,17 +59,47 @@ public class IssueWorkflowTest { public void should_list_statuses() throws Exception { workflow.start(); // order is important for UI - assertThat(workflow.statusKeys()).containsSequence(Issue.STATUS_OPEN, Issue.STATUS_REOPENED, Issue.STATUS_RESOLVED, Issue.STATUS_CLOSED); + assertThat(workflow.statusKeys()).containsSequence(Issue.STATUS_OPEN, Issue.STATUS_CONFIRMED, Issue.STATUS_REOPENED, Issue.STATUS_RESOLVED, Issue.STATUS_CLOSED); } @Test - public void should_list_out_manual_transitions() throws Exception { + public void should_list_out_manual_transitions_from_status_open() throws Exception { workflow.start(); DefaultIssue issue = new DefaultIssue().setStatus(Issue.STATUS_OPEN); List transitions = workflow.outTransitions(issue); - assertThat(transitions).hasSize(2); - assertThat(keys(transitions)).containsOnly("falsepositive", "resolve"); + assertThat(transitions).hasSize(3); + assertThat(keys(transitions)).containsOnly("confirm", "falsepositive", "resolve"); + } + + @Test + public void should_list_out_manual_transitions_from_status_confirmed() throws Exception { + workflow.start(); + + DefaultIssue issue = new DefaultIssue().setStatus(Issue.STATUS_CONFIRMED); + List transitions = workflow.outTransitions(issue); + assertThat(transitions).hasSize(3); + assertThat(keys(transitions)).containsOnly("unconfirm", "falsepositive", "resolve"); + } + + @Test + public void should_list_out_manual_transitions_from_status_resolved() throws Exception { + workflow.start(); + + DefaultIssue issue = new DefaultIssue().setStatus(Issue.STATUS_RESOLVED); + List transitions = workflow.outTransitions(issue); + assertThat(transitions).hasSize(1); + assertThat(keys(transitions)).containsOnly("reopen"); + } + + @Test + public void should_list_out_manual_transitions_from_status_reopen() throws Exception { + workflow.start(); + + DefaultIssue issue = new DefaultIssue().setStatus(Issue.STATUS_REOPENED); + List transitions = workflow.outTransitions(issue); + assertThat(transitions).hasSize(3); + assertThat(keys(transitions)).containsOnly("confirm", "resolve", "falsepositive"); } @Test diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java index 8ba23b9aa83..0b66844d16e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java @@ -23,6 +23,8 @@ package org.sonar.api.issue; * @since 3.6 */ public interface DefaultTransitions { + String CONFIRM = "confirm"; + String UNCONFIRM = "unconfirm"; String REOPEN = "reopen"; String RESOLVE = "resolve"; String FALSE_POSITIVE = "falsepositive"; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java index 36bf2abc812..4122e73212a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java @@ -36,6 +36,7 @@ public interface Issue extends Serializable { int MESSAGE_MAX_SIZE = 4000; String STATUS_OPEN = "OPEN"; + String STATUS_CONFIRMED = "CONFIRMED"; String STATUS_REOPENED = "REOPENED"; String STATUS_RESOLVED = "RESOLVED"; String STATUS_CLOSED = "CLOSED"; -- 2.39.5