aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common
diff options
context:
space:
mode:
authorPierre Guillot <50145663+pierre-guillot-sonarsource@users.noreply.github.com>2019-05-08 16:36:58 +0200
committerSonarTech <sonartech@sonarsource.com>2019-05-22 20:21:14 +0200
commit5d140eb1e005bb57f7d41dc952efdf11dead36ef (patch)
tree21ce793050dc4d172edbc01f42dc93f7c4a68d24 /server/sonar-server-common
parent864ad5894020f45953d2aac95b1b85744c242f7e (diff)
downloadsonarqube-5d140eb1e005bb57f7d41dc952efdf11dead36ef.tar.gz
sonarqube-5d140eb1e005bb57f7d41dc952efdf11dead36ef.zip
SONAR-12026 Add transition "Set as In Review" on Security Hotspots
Diffstat (limited to 'server/sonar-server-common')
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java16
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java25
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java245
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java117
4 files changed, 277 insertions, 126 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
index 11a45cb4946..4148b57c121 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
@@ -28,20 +28,20 @@ public class SecurityStandardCategoryStatistics {
private final String category;
private final long vulnerabilities;
private final OptionalInt vulnerabiliyRating;
+ private final long inReviewSecurityHotspots;
private final long toReviewSecurityHotspots;
- private final long openSecurityHotspots;
private final long wontFixSecurityHotspots;
private final List<SecurityStandardCategoryStatistics> children;
private long activeRules;
private long totalRules;
- public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long toReviewSecurityHotspots, long openSecurityHotspots,
- long wontFixSecurityHotspots, @Nullable List<SecurityStandardCategoryStatistics> children) {
+ public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long inReviewSecurityHotspots, long toReviewSecurityHotspots,
+ long wontFixSecurityHotspots, @Nullable List<SecurityStandardCategoryStatistics> children) {
this.category = category;
this.vulnerabilities = vulnerabilities;
this.vulnerabiliyRating = vulnerabiliyRating;
+ this.inReviewSecurityHotspots = inReviewSecurityHotspots;
this.toReviewSecurityHotspots = toReviewSecurityHotspots;
- this.openSecurityHotspots = openSecurityHotspots;
this.wontFixSecurityHotspots = wontFixSecurityHotspots;
this.children = children;
}
@@ -58,12 +58,12 @@ public class SecurityStandardCategoryStatistics {
return vulnerabiliyRating;
}
- public long getToReviewSecurityHotspots() {
- return toReviewSecurityHotspots;
+ public long getInReviewSecurityHotspots() {
+ return inReviewSecurityHotspots;
}
- public long getOpenSecurityHotspots() {
- return openSecurityHotspots;
+ public long getToReviewSecurityHotspots() {
+ return toReviewSecurityHotspots;
}
public long getWontFixSecurityHotspots() {
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 1a7cfe32e1b..eea7b1e28e7 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
@@ -39,6 +39,7 @@ import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED;
import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
import static org.sonar.api.issue.Issue.STATUS_CLOSED;
import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
+import static org.sonar.api.issue.Issue.STATUS_IN_REVIEW;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_REOPENED;
import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
@@ -61,7 +62,7 @@ public class IssueWorkflow implements Startable {
@Override
public void start() {
StateMachine.Builder builder = StateMachine.builder()
- .states(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED, STATUS_TO_REVIEW);
+ .states(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED, STATUS_TO_REVIEW, STATUS_IN_REVIEW);
buildManualTransitions(builder);
buildAutomaticTransitions(builder);
buildSecurityHotspotTransitions(builder);
@@ -149,6 +150,12 @@ public class IssueWorkflow implements Startable {
private static void buildSecurityHotspotTransitions(StateMachine.Builder builder) {
builder
+ .transition(Transition.builder(DefaultTransitions.SET_AS_IN_REVIEW)
+ .from(STATUS_TO_REVIEW).to(STATUS_IN_REVIEW)
+ .conditions(new HasType(RuleType.SECURITY_HOTSPOT))
+ .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN)
+ .build())
+
.transition(Transition.builder(DefaultTransitions.DETECT)
.from(STATUS_TO_REVIEW).to(STATUS_OPEN)
.conditions(new HasType(RuleType.SECURITY_HOTSPOT))
@@ -167,16 +174,6 @@ public class IssueWorkflow implements Startable {
.functions(new SetType(RuleType.SECURITY_HOTSPOT))
.requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN)
.build())
- .transition(Transition.builder(DefaultTransitions.REQUEST_REVIEW)
- .from(STATUS_OPEN).to(STATUS_RESOLVED)
- .conditions(IsManualVulnerability.INSTANCE)
- .functions(new SetType(RuleType.SECURITY_HOTSPOT), new SetResolution(RESOLUTION_FIXED))
- .build())
- .transition(Transition.builder(DefaultTransitions.REQUEST_REVIEW)
- .from(STATUS_REOPENED).to(STATUS_RESOLVED)
- .conditions(IsManualVulnerability.INSTANCE)
- .functions(new SetType(RuleType.SECURITY_HOTSPOT), new SetResolution(RESOLUTION_FIXED))
- .build())
.transition(Transition.builder(DefaultTransitions.REJECT)
.from(STATUS_RESOLVED).to(STATUS_REOPENED)
.conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED))
@@ -236,6 +233,12 @@ public class IssueWorkflow implements Startable {
.functions(SetClosed.INSTANCE, SetCloseDate.INSTANCE)
.automatic()
.build())
+ .transition(Transition.builder(AUTOMATIC_CLOSE_TRANSITION)
+ .from(STATUS_IN_REVIEW).to(STATUS_CLOSED)
+ .conditions(IsBeingClosed.INSTANCE, new HasType(RuleType.SECURITY_HOTSPOT))
+ .functions(SetClosed.INSTANCE, SetCloseDate.INSTANCE)
+ .automatic()
+ .build())
// Reopen issues that are marked as resolved but that are still alive.
.transition(Transition.builder("automaticreopen")
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
new file mode 100644
index 00000000000..03bb3584109
--- /dev/null
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java
@@ -0,0 +1,245 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue.workflow;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.time.DateUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.sonar.api.issue.DefaultTransitions;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RuleType;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
+import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.server.issue.IssueFieldsSetter;
+
+import static org.assertj.core.api.Assertions.assertThat;
+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_WONT_FIX;
+import static org.sonar.api.issue.Issue.STATUS_CLOSED;
+import static org.sonar.api.issue.Issue.STATUS_IN_REVIEW;
+import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
+import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW;
+import static org.sonar.db.rule.RuleTesting.XOO_X1;
+
+@RunWith(DataProviderRunner.class)
+public class IssueWorkflowForSecurityHotspotsTest {
+
+ private static final String[] ALL_STATUSES_LEADING_TO_CLOSED = new String[] {STATUS_TO_REVIEW, STATUS_IN_REVIEW, STATUS_RESOLVED};
+
+ private static final String[] SUPPORTED_RESOLUTIONS_FOR_UNCLOSING = new String[] {RESOLUTION_FIXED, RESOLUTION_REMOVED};
+
+ private IssueFieldsSetter updater = new IssueFieldsSetter();
+
+ private IssueWorkflow underTest = new IssueWorkflow(new FunctionExecutor(updater), updater);
+
+ @Test
+ public void list_out_transitions_in_status_to_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(STATUS_TO_REVIEW);
+
+ List<Transition> transitions = underTest.outTransitions(issue);
+
+ assertThat(keys(transitions)).containsOnly("setinreview", "detect", "clear");
+ }
+
+ @Test
+ public void list_out_transitions_in_status_in_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(STATUS_IN_REVIEW);
+
+ List<Transition> transitions = underTest.outTransitions(issue);
+
+ assertThat(keys(transitions)).isEmpty();
+ }
+
+ @Test
+ public void set_as_in_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .setIsFromHotspot(true)
+ .setStatus(STATUS_TO_REVIEW);
+
+ boolean result = underTest.doManualTransition(issue, DefaultTransitions.SET_AS_IN_REVIEW, IssueChangeContext.createUser(new Date(), "USER1"));
+
+ assertThat(result).isTrue();
+ assertThat(issue.getStatus()).isEqualTo(STATUS_IN_REVIEW);
+ assertThat(issue.resolution()).isNull();
+ }
+
+ @Test
+ public void automatically_close_resolved_security_hotspots_in_status_to_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .setResolution(null)
+ .setStatus(STATUS_TO_REVIEW)
+ .setNew(false)
+ .setBeingClosed(true);
+ Date now = new Date();
+
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.closeDate()).isNotNull();
+ assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
+ }
+
+ @Test
+ public void automatically_close_resolved_security_hotspots_in_status_in_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .setResolution(null)
+ .setStatus(STATUS_IN_REVIEW)
+ .setNew(false)
+ .setBeingClosed(true);
+ Date now = new Date();
+
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.closeDate()).isNotNull();
+ assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
+ }
+
+ @Test
+ @UseDataProvider("allStatusesLeadingToClosed")
+ public void do_not_automatically_reopen_closed_issues_of_security_hotspots(String previousStatus) {
+ DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
+ .map(resolution -> {
+ DefaultIssue issue = newClosedIssue(resolution);
+ setStatusPreviousToClosed(issue, previousStatus);
+ issue.setType(RuleType.SECURITY_HOTSPOT);
+ return issue;
+ })
+ .toArray(DefaultIssue[]::new);
+ Date now = new Date();
+ underTest.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.updateDate()).isNull();
+ });
+ }
+
+ @Test
+ public void doAutomaticTransition_does_nothing_on_security_hotspots_in_to_review_status() {
+ DefaultIssue issue = new DefaultIssue()
+ .setKey("ABCDE")
+ .setRuleKey(XOO_X1)
+ .setResolution(null)
+ .setStatus(STATUS_TO_REVIEW);
+
+ underTest.start();
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(new Date()));
+
+ assertThat(issue.status()).isEqualTo(STATUS_TO_REVIEW);
+ assertThat(issue.resolution()).isNull();
+ }
+
+ @Test
+ @UseDataProvider("allStatusesLeadingToClosed")
+ public void do_not_automatically_reopen_closed_issues_of_manual_vulnerability(String previousStatus) {
+ DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
+ .map(resolution -> {
+ DefaultIssue issue = newClosedIssue(resolution);
+ setStatusPreviousToClosed(issue, previousStatus);
+ issue.setIsFromHotspot(true);
+ return issue;
+ })
+ .toArray(DefaultIssue[]::new);
+ Date now = new Date();
+ underTest.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.updateDate()).isNull();
+ });
+ }
+
+ @DataProvider
+ public static Object[][] allStatusesLeadingToClosed() {
+ return Arrays.stream(ALL_STATUSES_LEADING_TO_CLOSED)
+ .map(t -> new Object[] {t})
+ .toArray(Object[][]::new);
+ }
+
+ @Test
+ public void do_not_allow_to_doManualTransition_when_condition_fails() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setKey("ABCDE")
+ // Detect is only available on hotspot
+ .setType(RuleType.VULNERABILITY)
+ .setIsFromHotspot(true)
+ .setStatus(STATUS_RESOLVED)
+ .setResolution(RESOLUTION_WONT_FIX)
+ .setRuleKey(XOO_X1);
+
+ assertThat(underTest.doManualTransition(issue, DefaultTransitions.DETECT, IssueChangeContext.createScan(new Date()))).isFalse();
+ }
+
+ private static DefaultIssue newClosedIssue(String resolution) {
+ return new DefaultIssue()
+ .setKey("ABCDE")
+ .setRuleKey(RuleKey.of("js", "S001"))
+ .setResolution(resolution)
+ .setStatus(STATUS_CLOSED)
+ .setNew(false)
+ .setCloseDate(new Date(5_999_999L));
+ }
+
+ private static void setStatusPreviousToClosed(DefaultIssue issue, String previousStatus) {
+ addStatusChange(issue, new Date(), previousStatus, STATUS_CLOSED);
+ }
+
+ private static void addStatusChange(DefaultIssue issue, Date date, String previousStatus, String newStatus) {
+ issue.addChange(new FieldDiffs().setCreationDate(date).setDiff("status", previousStatus, newStatus));
+ }
+
+ private Collection<String> keys(List<Transition> transitions) {
+ return Collections2.transform(transitions, new Function<Transition, String>() {
+ @Override
+ public String apply(@Nullable Transition transition) {
+ return transition.key();
+ }
+ });
+ }
+}
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 4151f7280b6..a8b7c9998d4 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
@@ -24,6 +24,7 @@ import com.google.common.collect.Collections2;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
@@ -36,7 +37,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.sonar.api.issue.DefaultTransitions;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.RuleType;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.issue.IssueChangeContext;
@@ -52,11 +52,11 @@ import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED;
import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
import static org.sonar.api.issue.Issue.STATUS_CLOSED;
import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
+import static org.sonar.api.issue.Issue.STATUS_IN_REVIEW;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_REOPENED;
import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW;
-import static org.sonar.db.rule.RuleTesting.XOO_X1;
@RunWith(DataProviderRunner.class)
public class IssueWorkflowTest {
@@ -68,7 +68,14 @@ public class IssueWorkflowTest {
@Test
public void list_statuses() {
underTest.start();
- assertThat(underTest.statusKeys()).containsExactly(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED, STATUS_TO_REVIEW);
+
+ List<String> expectedStatus = new ArrayList<>();
+ // issues statuses
+ expectedStatus.addAll(Arrays.asList(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED));
+ // hostpots statuses
+ expectedStatus.addAll(Arrays.asList(STATUS_TO_REVIEW, STATUS_IN_REVIEW));
+
+ assertThat(underTest.statusKeys()).containsExactlyInAnyOrder(expectedStatus.toArray(new String[]{}));
}
@Test
@@ -117,16 +124,6 @@ public class IssueWorkflowTest {
}
@Test
- public void list_out_transitions_from_security_hotspot_in_status_to_review() {
- underTest.start();
- DefaultIssue issue = new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(STATUS_TO_REVIEW);
-
- List<Transition> transitions = underTest.outTransitions(issue);
-
- assertThat(keys(transitions)).containsOnly("detect", "clear");
- }
-
- @Test
public void fail_if_unknown_status_when_listing_transitions() {
underTest.start();
@@ -159,27 +156,6 @@ public class IssueWorkflowTest {
}
@Test
- public void automatically_close_resolved_security_hotspots_in_to_review() {
- underTest.start();
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setType(RuleType.SECURITY_HOTSPOT)
- .setRuleKey(XOO_X1)
- .setResolution(null)
- .setStatus(STATUS_TO_REVIEW)
- .setNew(false)
- .setBeingClosed(true);
- Date now = new Date();
-
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
-
- assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
- assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
- assertThat(issue.closeDate()).isNotNull();
- assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
- }
-
- @Test
@UseDataProvider("allStatusesLeadingToClosed")
public void automatically_reopen_closed_issue_to_its_previous_status_from_changelog(String previousStatus) {
DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
@@ -328,64 +304,6 @@ public class IssueWorkflowTest {
});
}
- @Test
- @UseDataProvider("allStatusesLeadingToClosed")
- public void do_not_automatically_reopen_closed_issues_of_security_hotspots(String previousStatus) {
- DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
- .map(resolution -> {
- DefaultIssue issue = newClosedIssue(resolution);
- setStatusPreviousToClosed(issue, previousStatus);
- issue.setType(RuleType.SECURITY_HOTSPOT);
- return issue;
- })
- .toArray(DefaultIssue[]::new);
- Date now = new Date();
- underTest.start();
-
- Arrays.stream(issues).forEach(issue -> {
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
-
- assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
- assertThat(issue.updateDate()).isNull();
- });
- }
-
- @Test
- public void doAutomaticTransition_does_nothing_on_security_hotspots_in_to_review_status() {
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setRuleKey(XOO_X1)
- .setResolution(null)
- .setStatus(STATUS_TO_REVIEW);
-
- underTest.start();
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(new Date()));
-
- assertThat(issue.status()).isEqualTo(STATUS_TO_REVIEW);
- assertThat(issue.resolution()).isNull();
- }
-
- @Test
- @UseDataProvider("allStatusesLeadingToClosed")
- public void do_not_automatically_reopen_closed_issues_of_manual_vulnerability(String previousStatus) {
- DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
- .map(resolution -> {
- DefaultIssue issue = newClosedIssue(resolution);
- setStatusPreviousToClosed(issue, previousStatus);
- issue.setIsFromHotspot(true);
- return issue;
- })
- .toArray(DefaultIssue[]::new);
- Date now = new Date();
- underTest.start();
-
- Arrays.stream(issues).forEach(issue -> {
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
-
- assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
- assertThat(issue.updateDate()).isNull();
- });
- }
private static final String[] ALL_STATUSES_LEADING_TO_CLOSED = new String[] {STATUS_OPEN, STATUS_REOPENED, STATUS_CONFIRMED, STATUS_RESOLVED};
private static final String[] ALL_RESOLUTIONS_BEFORE_CLOSING = new String[] {
null,
@@ -511,21 +429,6 @@ public class IssueWorkflowTest {
assertThat(issue.assignee()).isNull();
}
- @Test
- public void do_not_allow_to_doManualTransition_when_condition_fails() {
- underTest.start();
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- // Detect is only available on hotspot
- .setType(RuleType.VULNERABILITY)
- .setIsFromHotspot(true)
- .setStatus(STATUS_RESOLVED)
- .setResolution(RESOLUTION_WONT_FIX)
- .setRuleKey(XOO_X1);
-
- assertThat(underTest.doManualTransition(issue, DefaultTransitions.DETECT, IssueChangeContext.createScan(new Date()))).isFalse();
- }
-
private static DefaultIssue newClosedIssue(String resolution) {
return new DefaultIssue()
.setKey("ABCDE")