]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14570 making text sent by email about QG more clear to the user
authorLukasz Jarocki <lukasz.jarocki@sonarsource.com>
Thu, 29 Apr 2021 06:31:43 +0000 (08:31 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 29 Apr 2021 20:03:27 +0000 (20:03 +0000)
server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplate.java
server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplateTest.java

index b67658a046aa70b16a3548f0148dd5bd7a41cc6f..4766df2eecbb085478e72559609b6fe793d6454a 100644 (file)
@@ -27,6 +27,9 @@ import org.sonar.api.measures.Metric;
 import org.sonar.api.notifications.Notification;
 import org.sonar.server.issue.notification.EmailMessage;
 import org.sonar.server.issue.notification.EmailTemplate;
+import org.sonar.server.measure.Rating;
+
+import java.util.regex.Pattern;
 
 /**
  * Creates email message for notification "alerts".
@@ -35,7 +38,9 @@ import org.sonar.server.issue.notification.EmailTemplate;
  */
 public class QGChangeEmailTemplate implements EmailTemplate {
 
-  private EmailSettings configuration;
+  private static final Pattern alertRatingRegex = Pattern.compile(".*>\\s\\d$");
+
+  private final EmailSettings configuration;
 
   public QGChangeEmailTemplate(EmailSettings configuration) {
     this.configuration = configuration;
@@ -111,11 +116,11 @@ public class QGChangeEmailTemplate implements EmailTemplate {
         messageBody.append("Quality gate threshold");
       }
       if (alerts.length == 1) {
-        messageBody.append(": ").append(alerts[0].trim()).append("\n");
+        messageBody.append(": ").append(formatRating(alerts[0].trim())).append("\n");
       } else {
         messageBody.append("s:\n");
         for (String alert : alerts) {
-          messageBody.append("  - ").append(alert.trim()).append("\n");
+          messageBody.append("  - ").append(formatRating(alert.trim())).append("\n");
         }
       }
     }
@@ -128,4 +133,29 @@ public class QGChangeEmailTemplate implements EmailTemplate {
     return messageBody.toString();
   }
 
+  /**
+   * Converts the ratings from digits to a rating letter {@see org.sonar.server.measure.Rating}, based on the
+   * raw text passed to this template.
+   *
+   * Examples:
+   * Reliability rating > 4 will be converted to Reliability rating worse than D
+   * Security rating on New Code > 1 will be converted to Security rating on New Code worse than A
+   * Code Coverage < 50% will not be converted and returned as is.
+   *
+   * @param alert
+   * @return full raw alert with converted ratings
+   */
+  private static String formatRating(String alert) {
+    if(!alertRatingRegex.matcher(alert).matches()) {
+      return alert;
+    }
+
+    StringBuilder builder = new StringBuilder();
+    builder.append(alert, 0, alert.length() - 3);
+    builder.append("worse than ");
+    String rating = alert.substring(alert.length() - 1);
+    builder.append(Rating.valueOf(Integer.parseInt(rating)).name());
+    return builder.toString();
+  }
+
 }
index a8e77877c13eb7ba050e4c76556b49d58df848ef..5a956a4df109ae283b06890603583f16361f5097 100644 (file)
  */
 package org.sonar.server.qualitygate.notification;
 
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.sonar.api.config.EmailSettings;
 import org.sonar.api.notifications.Notification;
 import org.sonar.server.issue.notification.EmailMessage;
@@ -31,6 +35,7 @@ import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+@RunWith(DataProviderRunner.class)
 public class QGChangeEmailTemplateTest {
 
   private QGChangeEmailTemplate template;
@@ -62,7 +67,7 @@ public class QGChangeEmailTemplateTest {
       "Quality gate status: Failed\n" +
       "\n" +
       "Quality gate thresholds:\n" +
-      "  - violations > 4\n" +
+      "  - violations worse than D\n" +
       "  - coverage < 75%\n" +
       "\n" +
       "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
@@ -83,7 +88,7 @@ public class QGChangeEmailTemplateTest {
       "Quality gate status: Failed\n" +
       "\n" +
       "Quality gate thresholds:\n" +
-      "  - violations > 4\n" +
+      "  - violations worse than D\n" +
       "  - coverage < 75%\n" +
       "\n" +
       "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature"));
@@ -102,7 +107,7 @@ public class QGChangeEmailTemplateTest {
       "Quality gate status: Failed\n" +
       "\n" +
       "New quality gate thresholds:\n" +
-      "  - violations > 4\n" +
+      "  - violations worse than D\n" +
       "  - coverage < 75%\n" +
       "\n" +
       "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
@@ -120,7 +125,7 @@ public class QGChangeEmailTemplateTest {
       "Version: V1-SNAP\n" +
       "Quality gate status: Failed\n" +
       "\n" +
-      "New quality gate threshold: violations > 4\n" +
+      "New quality gate threshold: violations worse than D\n" +
       "\n" +
       "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
   }
@@ -137,7 +142,23 @@ public class QGChangeEmailTemplateTest {
       "Project: Foo\n" +
       "Quality gate status: Failed\n" +
       "\n" +
-      "New quality gate threshold: violations > 4\n" +
+      "New quality gate threshold: violations worse than D\n" +
+      "\n" +
+      "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+  }
+
+  @Test
+  public void shouldFormatBackToGreenMessage() {
+    Notification notification = createNotification("Passed", "", "OK", "false");
+
+    EmailMessage message = template.format(notification);
+    assertThat(message.getMessageId(), is("alerts/45"));
+    assertThat(message.getSubject(), is("\"Foo\" is back to green"));
+    assertThat(message.getMessage(), is("" +
+      "Project: Foo\n" +
+      "Version: V1-SNAP\n" +
+      "Quality gate status: Passed\n" +
+      "\n" +
       "\n" +
       "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
   }
@@ -156,45 +177,58 @@ public class QGChangeEmailTemplateTest {
       "Version: V1-SNAP\n" +
       "Quality gate status: Failed\n" +
       "\n" +
-      "New quality gate threshold: violations > 4\n" +
+      "New quality gate threshold: violations worse than D\n" +
       "\n" +
       "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature"));
   }
 
   @Test
-  public void shouldFormatBackToGreenMessage() {
-    Notification notification = createNotification("Passed", "", "OK", "false");
+  public void shouldFormatBackToGreenMessageOnBranch() {
+    Notification notification = createNotification("Passed", "", "OK", "false")
+        .setFieldValue("branch", "feature");
 
     EmailMessage message = template.format(notification);
     assertThat(message.getMessageId(), is("alerts/45"));
-    assertThat(message.getSubject(), is("\"Foo\" is back to green"));
+    assertThat(message.getSubject(), is("\"Foo (feature)\" is back to green"));
     assertThat(message.getMessage(), is("" +
       "Project: Foo\n" +
+      "Branch: feature\n" +
       "Version: V1-SNAP\n" +
       "Quality gate status: Passed\n" +
       "\n" +
       "\n" +
-      "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+      "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature"));
+  }
+
+  @DataProvider
+  public static Object[][] alertTextAndFormattedText() {
+    return new Object[][] {
+      {"violations > 1", "violations worse than A"},
+      {"violations > 4", "violations worse than D"},
+      {"Code Coverage < 50%", "Code Coverage < 50%"},
+      {"custom metric condition not met", "custom metric condition not met"}
+    };
   }
 
+  @UseDataProvider("alertTextAndFormattedText")
   @Test
-  public void shouldFormatBackToGreenMessageOnBranch() {
-    Notification notification = createNotification("Passed", "", "OK", "false")
-        .setFieldValue("branch", "feature");
+  public void shouldFormatNewAlertWithThresholdProperlyFormatted(String alertText, String expectedFormattedAlertText) {
+    Notification notification = createNotification("Failed", alertText, "ERROR", "true");
 
     EmailMessage message = template.format(notification);
     assertThat(message.getMessageId(), is("alerts/45"));
-    assertThat(message.getSubject(), is("\"Foo (feature)\" is back to green"));
+    assertThat(message.getSubject(), is("New quality gate threshold reached on \"Foo\""));
     assertThat(message.getMessage(), is("" +
       "Project: Foo\n" +
-      "Branch: feature\n" +
       "Version: V1-SNAP\n" +
-      "Quality gate status: Passed\n" +
+      "Quality gate status: Failed\n" +
       "\n" +
+      "New quality gate threshold: " + expectedFormattedAlertText + "\n" +
       "\n" +
-      "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature"));
+      "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
   }
 
+
   private Notification createNotification(String alertName, String alertText, String alertLevel, String isNewAlert) {
     return new Notification("alerts")
         .setFieldValue("projectName", "Foo")