]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22030 make sure field anticipatedTransitions is never null (#10949)
authorNgx <108925779+nicolas-gouteux-sonarsource@users.noreply.github.com>
Thu, 11 Apr 2024 13:19:51 +0000 (15:19 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 11 Apr 2024 20:02:47 +0000 (20:02 +0000)
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TransitionIssuesToAnticipatedStatesVisitor.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TransitionIssuesToAnticipatedStatesVisitorTest.java

index 9a9ddf0b9999e8a9b50f5b080d10a151e28a6a18..ea5c35927c4319e46487fedba0ed761451f8df74 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.issue;
 
 import java.time.Instant;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import org.apache.logging.log4j.util.Strings;
@@ -53,7 +54,8 @@ public class TransitionIssuesToAnticipatedStatesVisitor extends IssueVisitor {
 
   private final AnticipatedTransitionRepository anticipatedTransitionRepository;
 
-  public TransitionIssuesToAnticipatedStatesVisitor(AnticipatedTransitionRepository anticipatedTransitionRepository, IssueLifecycle issueLifecycle, CeTaskMessages ceTaskMessages) {
+  public TransitionIssuesToAnticipatedStatesVisitor(AnticipatedTransitionRepository anticipatedTransitionRepository,
+    IssueLifecycle issueLifecycle, CeTaskMessages ceTaskMessages) {
     this.anticipatedTransitionRepository = anticipatedTransitionRepository;
     this.issueLifecycle = issueLifecycle;
     this.ceTaskMessages = ceTaskMessages;
@@ -63,6 +65,8 @@ public class TransitionIssuesToAnticipatedStatesVisitor extends IssueVisitor {
   public void beforeComponent(Component component) {
     if (FILE.equals(component.getType())) {
       anticipatedTransitions = anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component);
+    } else {
+      anticipatedTransitions = Collections.emptyList();
     }
   }
 
@@ -104,5 +108,4 @@ public class TransitionIssuesToAnticipatedStatesVisitor extends IssueVisitor {
     String componentKey = componentKeyLength > MAX_LENGTH ? ("..." + issue.componentKey().substring(componentKeyLength - MAX_LENGTH, componentKeyLength)) : issue.componentKey();
     return String.format(TRANSITION_ERROR_TEMPLATE.replace("{}", "%s"), issue.getLine(), componentKey, e.getMessage());
   }
-
 }
index 8c8c6e36e067bdfe9802de848ff298641023e3d1..94a74d9dbd1c0cf158a67d48ccbb7c595f7f2464 100644 (file)
@@ -50,6 +50,7 @@ import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
 
 public class TransitionIssuesToAnticipatedStatesVisitorTest {
+
   @Rule
   public LogTester logTester = new LogTester();
   private final IssueLifecycle issueLifecycle = mock(IssueLifecycle.class);
@@ -58,12 +59,14 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest {
 
   private final CeTaskMessages ceTaskMessages = mock(CeTaskMessages.class);
 
-  private final TransitionIssuesToAnticipatedStatesVisitor underTest = new TransitionIssuesToAnticipatedStatesVisitor(anticipatedTransitionRepository, issueLifecycle, ceTaskMessages);
+  private final TransitionIssuesToAnticipatedStatesVisitor underTest =
+    new TransitionIssuesToAnticipatedStatesVisitor(anticipatedTransitionRepository, issueLifecycle, ceTaskMessages);
 
   @Test
   public void givenMatchingAnticipatedTransitions_transitionsShouldBeAppliedToIssues() {
     Component component = getComponent(Component.Type.FILE);
-    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component)).thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
+    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component))
+      .thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
 
     DefaultIssue issue = getDefaultIssue(1, "abcdefghi", "issue message");
 
@@ -81,7 +84,8 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest {
     Component component = getComponent(Component.Type.FILE);
     String exceptionMessage = "Cannot apply transition";
 
-    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component)).thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
+    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component))
+      .thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
     doThrow(new IllegalStateException(exceptionMessage)).when(issueLifecycle).doManualTransition(any(), any(), any());
     DefaultIssue issue = getDefaultIssue(1, "abcdefghi", "issue message");
     issue.setComponentKey(component.getKey());
@@ -101,7 +105,8 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest {
   @Test
   public void givenMatchingAnticipatedTransitionsOnResolvedIssue_transitionsShouldNotBeAppliedToIssues() {
     Component component = getComponent(Component.Type.FILE);
-    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component)).thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
+    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component))
+      .thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
 
     DefaultIssue issue = getDefaultIssue(1, "abcdefghi", "issue message");
     issue.setStatus(STATUS_RESOLVED);
@@ -117,7 +122,8 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest {
   @Test
   public void givenMatchingAnticipatedTransitions_whenIssueIsNotNew_transitionsShouldNotBeAppliedToIssues() {
     Component component = getComponent(Component.Type.FILE);
-    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component)).thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
+    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component))
+      .thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
 
     DefaultIssue issue = getDefaultIssue(1, "abcdefghi", "issue message");
     issue.setNew(false);
@@ -133,7 +139,8 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest {
   @Test
   public void givenNonMatchingAnticipatedTransitions_transitionsAreNotAppliedToIssues() {
     Component component = getComponent(Component.Type.FILE);
-    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component)).thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
+    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component))
+      .thenReturn(getAnticipatedTransitions("projectKey", "fileName"));
 
     DefaultIssue issue = getDefaultIssue(2, "abcdefghf", "another issue message");
 
@@ -148,7 +155,8 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest {
   @Test
   public void givenMatchingAnticipatedTransitionsWithEmptyComment_transitionsShouldBeAppliedToIssuesAndDefaultCommentApplied() {
     Component component = getComponent(Component.Type.FILE);
-    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component)).thenReturn(getAnticipatedTransitionsWithEmptyComment("projectKey", "fileName"));
+    when(anticipatedTransitionRepository.getAnticipatedTransitionByComponent(component))
+      .thenReturn(getAnticipatedTransitionsWithEmptyComment("projectKey", "fileName"));
 
     DefaultIssue issue = getDefaultIssue(1, "abcdefghi", "issue message");
 
@@ -181,12 +189,25 @@ public class TransitionIssuesToAnticipatedStatesVisitorTest {
     verifyNoInteractions(anticipatedTransitionRepository);
   }
 
+  @Test
+  public void givenAProjecComponent_the_issue_is_not_affected() {
+    Component component = getComponent(PROJECT);
+    DefaultIssue issue = getDefaultIssue(1, "abcdefghi", "issue message");
+
+    underTest.beforeComponent(component);
+    underTest.onIssue(component, issue);
+    assertThat(issue.getAnticipatedTransitionUuid()).isEmpty();
+    assertThat(issue.isBeingClosed()).isFalse();
+  }
+
   private Collection<AnticipatedTransition> getAnticipatedTransitions(String projecKey, String fileName) {
-    return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1, "abcdefghi", DefaultTransitions.ACCEPT, "doing the transition in an anticipated way")).toList();
+    return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1,
+      "abcdefghi", DefaultTransitions.ACCEPT, "doing the transition in an anticipated way")).toList();
   }
 
   private Collection<AnticipatedTransition> getAnticipatedTransitionsWithEmptyComment(String projecKey, String fileName) {
-    return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1, "abcdefghi", DefaultTransitions.ACCEPT, null)).toList();
+    return Stream.of(new AnticipatedTransition("atuuid", projecKey, "admin", RuleKey.parse("repo:id"), "issue message", fileName, 1,
+      "abcdefghi", DefaultTransitions.ACCEPT, null)).toList();
   }
 
   private Component getComponent(Component.Type type) {