]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4188 Close issues when resource has been moved or has been deleted
authorJulien Lancelot <julien.lancelot@gmail.com>
Thu, 18 Apr 2013 07:36:50 +0000 (09:36 +0200)
committerJulien Lancelot <julien.lancelot@gmail.com>
Thu, 18 Apr 2013 07:36:50 +0000 (09:36 +0200)
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssuesWorkflowDecorator.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssuesWorkflowDecoratorTest.java
sonar-batch/src/main/java/org/sonar/batch/issue/InitialOpenIssuesStack.java

index 4a69f7e16030af61f151f23956b210d0cda72724..26552d58fa52a895c82060059898600f8a5a79d2 100644 (file)
@@ -76,14 +76,16 @@ public class IssuesWorkflowDecorator implements Decorator {
       issueTracking.track(resource, openIssues, newDefaultIssues);
       updateIssues(newDefaultIssues);
 
-      addManualIssuesAndCloseResolvedOnes(openIssues, resource);
-      closeResolvedStandardIssues(openIssues, newIssues, resource);
-      keepFalsePositiveIssues(openIssues, resource);
-      reopenUnresolvedIssues(openIssues, resource);
+      Set<String> issueKeys = Sets.newHashSet(Collections2.transform(newIssues, new IssueToKeyfunction()));
+      for (IssueDto openIssue : openIssues) {
+        addManualIssuesAndCloseResolvedOnes(openIssue, resource);
+        closeResolvedStandardIssues(openIssue, issueKeys, resource);
+        keepFalsePositiveIssues(openIssue, resource);
+        reopenUnresolvedIssues(openIssue, resource);
+      }
 
       if (ResourceUtils.isRootProject(resource)) {
-        // TODO be carefullto take updated openIssue and not the ones coming directly from db (We should probably use a different sensor)
-//        closeIssuesOnDeletedResources(openIssues, resource);
+        closeIssuesOnDeletedResources(initialOpenIssuesStack.getAllIssues(), resource);
       }
     }
   }
@@ -94,46 +96,37 @@ public class IssuesWorkflowDecorator implements Decorator {
     }
   }
 
-  private void addManualIssuesAndCloseResolvedOnes(Collection<IssueDto> openIssues, Resource resource) {
-    for (IssueDto openIssue : openIssues) {
-      if (openIssue.isManualIssue()) {
-        DefaultIssue issue = toIssue(openIssue, resource);
-        if (Issue.STATUS_RESOLVED.equals(issue.status())) {
-          close(issue);
-        }
-        moduleIssues.addOrUpdate(issue);
+  private void addManualIssuesAndCloseResolvedOnes(IssueDto openIssue, Resource resource) {
+    if (openIssue.isManualIssue()) {
+      DefaultIssue issue = toIssue(openIssue, resource);
+      if (Issue.STATUS_RESOLVED.equals(issue.status())) {
+        close(issue);
       }
+      moduleIssues.addOrUpdate(issue);
     }
   }
 
-  private void closeResolvedStandardIssues(Collection<IssueDto> openIssues, Collection<Issue> issues, Resource resource) {
-    Set<String> issueKeys = Sets.newHashSet(Collections2.transform(issues, new IssueToKeyfunction()));
-
-    for (IssueDto openIssue : openIssues) {
-      if (!openIssue.isManualIssue() && !issueKeys.contains(openIssue.getUuid())) {
-        closeAndSave(openIssue, resource);
-      }
+  private void closeResolvedStandardIssues(IssueDto openIssue, Set<String> issueKeys, Resource resource) {
+    if (!openIssue.isManualIssue() && !issueKeys.contains(openIssue.getUuid())) {
+      closeAndSave(openIssue, resource);
     }
   }
 
-  private void keepFalsePositiveIssues(Collection<IssueDto> openIssues, Resource resource) {
-    for (IssueDto openIssue : openIssues) {
-      if (!openIssue.isManualIssue() && Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution())) {
-        DefaultIssue issue = toIssue(openIssue, resource);
-        issue.setResolution(openIssue.getResolution());
-        issue.setStatus(openIssue.getStatus());
-        issue.setUpdatedAt(new Date());
-        moduleIssues.addOrUpdate(issue);
-      }
+  private void keepFalsePositiveIssues(IssueDto openIssue, Resource resource) {
+    if (!openIssue.isManualIssue() && Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution())) {
+      DefaultIssue issue = toIssue(openIssue, resource);
+      issue.setResolution(openIssue.getResolution());
+      issue.setStatus(openIssue.getStatus());
+      issue.setUpdatedAt(new Date());
+      moduleIssues.addOrUpdate(issue);
     }
+
   }
 
-  private void reopenUnresolvedIssues(Collection<IssueDto> openIssues, Resource resource) {
-    for (IssueDto openIssue : openIssues) {
-      if (Issue.STATUS_RESOLVED.equals(openIssue.getStatus()) && !Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution())
-          && !openIssue.isManualIssue()) {
-        reopenAndSave(openIssue, resource);
-      }
+  private void reopenUnresolvedIssues(IssueDto openIssue, Resource resource) {
+    if (Issue.STATUS_RESOLVED.equals(openIssue.getStatus()) && !Issue.RESOLUTION_FALSE_POSITIVE.equals(openIssue.getResolution())
+        && !openIssue.isManualIssue()) {
+      reopenAndSave(openIssue, resource);
     }
   }
 
index 5f4bd71fdb8d4617e0b2180b4b5ad028b023ba9c..bb89f11eb1b52573180d21b7776efd569f1d2c08 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.plugins.core.issue;
 
 import com.google.common.collect.Lists;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.issue.Issue;
@@ -144,18 +143,18 @@ public class IssuesWorkflowDecoratorTest extends AbstractDaoTestCase {
   }
 
   @Test
-  @Ignore
   public void should_close_remaining_open_issue_on_root_project() {
     when(moduleIssues.issues(anyString())).thenReturn(Collections.<Issue>emptyList());
-    when(initialOpenIssuesStack.selectAndRemove(anyInt())).thenReturn(newArrayList(
-        new IssueDto().setUuid("100").setRuleId(1)));
+    when(initialOpenIssuesStack.selectAndRemove(anyInt())).thenReturn(Collections.<IssueDto>emptyList());
+
+    when(initialOpenIssuesStack.getAllIssues()).thenReturn(newArrayList(new IssueDto().setUuid("100").setRuleId(1)));
 
     Resource resource = mock(Resource.class);
     when(resource.getQualifier()).thenReturn(Qualifiers.PROJECT);
     decorator.decorate(resource, null);
 
     ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
-    verify(moduleIssues, times(2)).addOrUpdate(argument.capture());
+    verify(moduleIssues).addOrUpdate(argument.capture());
     assertThat(argument.getValue().status()).isEqualTo(Issue.STATUS_CLOSED);
     assertThat(argument.getValue().updatedAt()).isNotNull();
   }
index f6b6dec817a74eb336fe1ee551efb463c9afd280..ba070cfd0840cbdd6b8c35a8abc1ca4a31e80e84 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.sonar.batch.issue;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ListMultimap;
@@ -56,8 +55,7 @@ public class InitialOpenIssuesStack implements BatchExtension {
     }
   }
 
-  @VisibleForTesting
-  Collection<IssueDto> getAllIssues(){
+  public Collection<IssueDto> getAllIssues(){
     return issuesByResourceId.values();
   }
 }