From 0fe19fcf4e8236de5206bfb0fabd22f97065c374 Mon Sep 17 00:00:00 2001 From: Klaudio Sinani Date: Wed, 9 Mar 2022 10:10:29 +0100 Subject: SONAR-16101 Introduce new `acknowledged` resolution type for reviewed hotspots --- .../sonar/server/issue/workflow/IssueWorkflow.java | 26 +++++++++++++++++----- .../IssueWorkflowForSecurityHotspotsTest.java | 12 +++++----- 2 files changed, 28 insertions(+), 10 deletions(-) (limited to 'server/sonar-server-common') 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 f3b53317538..27885813c86 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 @@ -33,6 +33,7 @@ import org.sonar.server.issue.IssueFieldsSetter; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import static org.sonar.api.issue.Issue.RESOLUTION_ACKNOWLEDGED; import static org.sonar.api.issue.Issue.RESOLUTION_FALSE_POSITIVE; import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED; @@ -159,7 +160,7 @@ public class IssueWorkflow implements Startable { } private static void buildSecurityHotspotTransitions(StateMachine.Builder builder) { - // hotspot reviewed as fixed, either from TO_REVIEW or from REVIEWED-SAFE + // hotspot reviewed as fixed, either from TO_REVIEW or from REVIEWED-SAFE or from REVIEWED-ACKNOWLEDGED Transition.TransitionBuilder reviewedAsFixedBuilder = Transition.builder(DefaultTransitions.RESOLVE_AS_REVIEWED) .to(STATUS_REVIEWED) .conditions(new HasType(RuleType.SECURITY_HOTSPOT)) @@ -172,10 +173,10 @@ public class IssueWorkflow implements Startable { .build()) .transition(reviewedAsFixedBuilder .from(STATUS_REVIEWED) - .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_SAFE)) + .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_SAFE, RESOLUTION_ACKNOWLEDGED)) .build()); - // hotspot reviewed as safe, either from TO_REVIEW or from REVIEWED-FIXED + // hotspot reviewed as safe, either from TO_REVIEW or from REVIEWED-FIXED or from REVIEWED-ACKNOWLEDGED Transition.TransitionBuilder resolveAsSafeTransitionBuilder = Transition.builder(DefaultTransitions.RESOLVE_AS_SAFE) .to(STATUS_REVIEWED) .functions(new SetResolution(RESOLUTION_SAFE)) @@ -187,14 +188,29 @@ public class IssueWorkflow implements Startable { .build()) .transition(resolveAsSafeTransitionBuilder .from(STATUS_REVIEWED) - .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED)) + .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED, RESOLUTION_ACKNOWLEDGED)) + .build()); + + // hotspot reviewed as acknowledged, either from TO_REVIEW or from REVIEWED-FIXED or from REVIEWED-SAFE + Transition.TransitionBuilder resolveAsAcknowledgedTransitionBuilder = Transition.builder(DefaultTransitions.RESOLVE_AS_ACKNOWLEDGED) + .to(STATUS_REVIEWED) + .functions(new SetResolution(RESOLUTION_ACKNOWLEDGED)) + .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN); + builder + .transition(resolveAsAcknowledgedTransitionBuilder + .from(STATUS_TO_REVIEW) + .conditions(new HasType(RuleType.SECURITY_HOTSPOT)) + .build()) + .transition(resolveAsAcknowledgedTransitionBuilder + .from(STATUS_REVIEWED) + .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED, RESOLUTION_SAFE)) .build()); // put hotspot back into TO_REVIEW builder .transition(Transition.builder(DefaultTransitions.RESET_AS_TO_REVIEW) .from(STATUS_REVIEWED).to(STATUS_TO_REVIEW) - .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED, RESOLUTION_SAFE)) + .conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED, RESOLUTION_SAFE, RESOLUTION_ACKNOWLEDGED)) .functions(new SetResolution(null)) .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN) .build()); diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java index c70f2437df6..6e7bdcd7a24 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java @@ -42,8 +42,10 @@ import org.sonar.server.issue.IssueFieldsSetter; import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.issue.DefaultTransitions.RESET_AS_TO_REVIEW; +import static org.sonar.api.issue.DefaultTransitions.RESOLVE_AS_ACKNOWLEDGED; import static org.sonar.api.issue.DefaultTransitions.RESOLVE_AS_REVIEWED; import static org.sonar.api.issue.DefaultTransitions.RESOLVE_AS_SAFE; +import static org.sonar.api.issue.Issue.RESOLUTION_ACKNOWLEDGED; import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED; import static org.sonar.api.issue.Issue.RESOLUTION_SAFE; @@ -57,6 +59,7 @@ import static org.sonar.server.issue.workflow.IssueWorkflowTest.emptyIfNull; @RunWith(DataProviderRunner.class) public class IssueWorkflowForSecurityHotspotsTest { private static final IssueChangeContext SOME_CHANGE_CONTEXT = IssueChangeContext.createUser(new Date(), "USER1"); + private static final List RESOLUTION_TYPES = List.of(RESOLUTION_FIXED, RESOLUTION_SAFE, RESOLUTION_ACKNOWLEDGED); private final IssueFieldsSetter updater = new IssueFieldsSetter(); private final IssueWorkflow underTest = new IssueWorkflow(new FunctionExecutor(updater), updater); @@ -69,7 +72,7 @@ public class IssueWorkflowForSecurityHotspotsTest { List transitions = underTest.outTransitions(hotspot); - assertThat(keys(transitions)).containsExactlyInAnyOrder(RESOLVE_AS_REVIEWED, RESOLVE_AS_SAFE); + assertThat(keys(transitions)).containsExactlyInAnyOrder(RESOLVE_AS_REVIEWED, RESOLVE_AS_SAFE, RESOLVE_AS_ACKNOWLEDGED); } @DataProvider @@ -90,7 +93,7 @@ public class IssueWorkflowForSecurityHotspotsTest { List transitions = underTest.outTransitions(hotspot); - assertThat(keys(transitions)).containsExactlyInAnyOrder(RESOLVE_AS_SAFE, RESET_AS_TO_REVIEW); + assertThat(keys(transitions)).containsExactlyInAnyOrder(RESOLVE_AS_SAFE, RESET_AS_TO_REVIEW, RESOLVE_AS_ACKNOWLEDGED); } @Test @@ -100,7 +103,7 @@ public class IssueWorkflowForSecurityHotspotsTest { List transitions = underTest.outTransitions(hotspot); - assertThat(keys(transitions)).containsExactlyInAnyOrder(RESOLVE_AS_REVIEWED, RESET_AS_TO_REVIEW); + assertThat(keys(transitions)).containsExactlyInAnyOrder(RESOLVE_AS_REVIEWED, RESET_AS_TO_REVIEW, RESOLVE_AS_ACKNOWLEDGED); } @Test @@ -121,8 +124,7 @@ public class IssueWorkflowForSecurityHotspotsTest { Issue.SECURITY_HOTSPOT_RESOLUTIONS.stream(), Stream.of(randomAlphabetic(12))) .flatMap(t -> t) - .filter(t -> !RESOLUTION_FIXED.equals(t)) - .filter(t -> !RESOLUTION_SAFE.equals(t)) + .filter(t -> !RESOLUTION_TYPES.contains(t)) .map(t -> new Object[] {t}) .toArray(Object[][]::new); } -- cgit v1.2.3