aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common/src/test/java/org
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2018-08-14 18:07:10 +0200
committerSonarTech <sonartech@sonarsource.com>2018-08-21 20:21:05 +0200
commit3065f6824c72d504c8e317c7d2d6a2c682081c4f (patch)
treeaa9a369907d4c31f3225e81f6073de77ba887d9e /server/sonar-server-common/src/test/java/org
parent61c813392f60ec29e4b628e7244593c627058b5b (diff)
downloadsonarqube-3065f6824c72d504c8e317c7d2d6a2c682081c4f.tar.gz
sonarqube-3065f6824c72d504c8e317c7d2d6a2c682081c4f.zip
SONAR-8368 reopen closed issues (restore status)
but those from Hotspots rules and manual vulnerabilities
Diffstat (limited to 'server/sonar-server-common/src/test/java/org')
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java155
1 files changed, 155 insertions, 0 deletions
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 bc508bd450d..c515234fd08 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
@@ -21,6 +21,10 @@ 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;
@@ -28,16 +32,21 @@ 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.apache.commons.lang.time.DateUtils.addDays;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
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;
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;
@@ -45,6 +54,7 @@ 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;
+@RunWith(DataProviderRunner.class)
public class IssueWorkflowTest {
IssueFieldsSetter updater = new IssueFieldsSetter();
@@ -148,6 +158,151 @@ public class IssueWorkflowTest {
}
@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)
+ .map(resolution -> {
+ DefaultIssue issue = newClosedIssue(resolution);
+ setStatusPreviousToClosed(issue, previousStatus);
+ return issue;
+ })
+ .toArray(DefaultIssue[]::new);
+ Date now = new Date();
+ workflow.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(previousStatus);
+ assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
+ assertThat(issue.closeDate()).isNull();
+ assertThat(issue.isChanged()).isTrue();
+ });
+ }
+
+ @Test
+ @UseDataProvider("allStatusesLeadingToClosed")
+ public void automatically_reopen_closed_issue_to_most_recent_previous_status_from_changelog(String previousStatus) {
+ DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
+ .map(resolution -> {
+ DefaultIssue issue = newClosedIssue(resolution);
+ Date now = new Date();
+ addStatusChange(issue, addDays(now, -60), STATUS_OPEN, STATUS_CONFIRMED);
+ addStatusChange(issue, addDays(now, -10), STATUS_CONFIRMED, previousStatus);
+ addStatusChange(issue, now, previousStatus, STATUS_CLOSED);
+ return issue;
+ })
+ .toArray(DefaultIssue[]::new);
+ Date now = new Date();
+ workflow.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(previousStatus);
+ assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
+ });
+ }
+
+ @DataProvider
+ public static Object[][] allStatusesLeadingToClosed() {
+ return new Object[][] {
+ {STATUS_OPEN},
+ {STATUS_REOPENED},
+ {STATUS_CONFIRMED},
+ {STATUS_RESOLVED}
+ };
+ }
+
+ private static final String[] SUPPORTED_RESOLUTIONS_FOR_UNCLOSING = new String[] {RESOLUTION_FIXED, RESOLUTION_REMOVED};
+
+ @DataProvider
+ public static Object[][] supportedResolutionsForUnClosing() {
+ return Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
+ .map(t -> new Object[] {t})
+ .toArray(Object[][]::new);
+ }
+
+ @Test
+ public void do_not_automatically_reopen_closed_issue_which_have_no_previous_status_in_changelog() {
+ DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
+ .map(IssueWorkflowTest::newClosedIssue)
+ .toArray(DefaultIssue[]::new);
+ Date now = new Date();
+ workflow.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.updateDate()).isNull();
+ });
+ }
+
+ @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();
+ workflow.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.updateDate()).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();
+ workflow.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ workflow.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.updateDate()).isNull();
+ });
+ }
+
+ private static DefaultIssue newClosedIssue(String resolution) {
+ DefaultIssue res = new DefaultIssue()
+ .setKey("ABCDE")
+ .setRuleKey(RuleKey.of("js", "S001"))
+ .setResolution(resolution)
+ .setStatus(STATUS_CLOSED)
+ .setNew(false)
+ .setCloseDate(new Date(5_999_999L));
+ return res;
+ }
+
+ 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));
+ }
+
+ @Test
public void close_open_dead_issue() {
workflow.start();