]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9442 add names of changed quality profiles in mail notification
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 20 Jun 2017 13:38:20 +0000 (15:38 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 29 Jun 2017 15:23:19 +0000 (17:23 +0200)
16 files changed:
it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java
it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSender.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSenderTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplateTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java
tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java
tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java
tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java

index 522bc81483d0891c8b1f0c400a321d955bd480b8..a2b2d237b01f8cfc651eb0f787fd216ed9cc7edf 100644 (file)
@@ -24,7 +24,7 @@ import org.sonar.api.resources.Language;
 public class Foo implements Language {
 
   public static final String KEY = "foo";
-  public static final String NAME = "foo";
+  public static final String NAME = "Foo";
 
   @Override
   public String getKey() {
index 522bc81483d0891c8b1f0c400a321d955bd480b8..a2b2d237b01f8cfc651eb0f787fd216ed9cc7edf 100644 (file)
@@ -24,7 +24,7 @@ import org.sonar.api.resources.Language;
 public class Foo implements Language {
 
   public static final String KEY = "foo";
-  public static final String NAME = "foo";
+  public static final String NAME = "Foo";
 
   @Override
   public String getKey() {
index 39c20db53c7e17d649e4cdd274c503aa5d2cffb3..7c6e83e469fe02ab28ca6aaf026e31c5b1e0a3a8 100644 (file)
@@ -29,8 +29,8 @@ import org.sonar.server.qualitygate.RegisterQualityGates;
 import org.sonar.server.qualityprofile.BuiltInQProfileInsertImpl;
 import org.sonar.server.qualityprofile.BuiltInQProfileLoader;
 import org.sonar.server.qualityprofile.BuiltInQProfileUpdateImpl;
-import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification;
 import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationDispatcher;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationSender;
 import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationTemplate;
 import org.sonar.server.qualityprofile.RegisterQualityProfiles;
 import org.sonar.server.rule.RegisterRules;
@@ -66,7 +66,7 @@ public class PlatformLevelStartup extends PlatformLevel {
       NotificationModule.class,
       BuiltInQualityProfilesNotificationDispatcher.class,
       BuiltInQualityProfilesNotificationTemplate.class,
-      BuiltInQualityProfilesNotification.class,
+      BuiltInQualityProfilesNotificationSender.class,
       BuiltInQProfileInsertImpl.class,
       BuiltInQProfileUpdateImpl.class,
       RegisterQualityProfiles.class,
index cdc2b657748f152767171ea2c6f02eb2f75c207b..9c2a906147ca9c82658822223056527902b5bdb7 100644 (file)
 
 package org.sonar.server.qualityprofile;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
 import org.sonar.api.notifications.Notification;
-import org.sonar.server.notification.NotificationManager;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationSender.BUILT_IN_QUALITY_PROFILES;
 
 public class BuiltInQualityProfilesNotification {
 
-  static final String BUILT_IN_QUALITY_PROFILES = "built-in-quality-profiles";
+  private static final String NUMBER_OF_PROFILES = "numberOfProfiles";
+  private static final String PROFILE_NAME = ".profileName";
+  private static final String LANGUAGE = ".language";
+  private final List<Profile> profiles = new ArrayList<>();
 
-  private final NotificationManager notificationManager;
+  public BuiltInQualityProfilesNotification addProfile(Profile profile) {
+    profiles.add(profile);
+    return this;
+  }
 
-  public BuiltInQualityProfilesNotification(NotificationManager notificationManager) {
-    this.notificationManager = notificationManager;
+  public Notification serialize() {
+    Notification notification = new Notification(BUILT_IN_QUALITY_PROFILES);
+    notification.setFieldValue(NUMBER_OF_PROFILES, String.valueOf(profiles.size()));
+    AtomicInteger count = new AtomicInteger();
+    profiles.forEach(profile -> {
+      int index = count.getAndIncrement();
+      notification.setFieldValue(index + ".profileName", profile.getProfileName());
+      notification.setFieldValue(index + ".language", profile.getLanguage());
+    });
+    return notification;
   }
 
-  void send() {
-    notificationManager.scheduleForSending(
-      new Notification(BUILT_IN_QUALITY_PROFILES)
-        .setDefaultMessage("This is a test message from SonarQube"));
+  public static BuiltInQualityProfilesNotification parse(Notification notification) {
+    checkState(BUILT_IN_QUALITY_PROFILES.equals(notification.getType()),
+      "Expected notification of type %s but got %s", BUILT_IN_QUALITY_PROFILES, notification.getType());
+    BuiltInQualityProfilesNotification notif = new BuiltInQualityProfilesNotification();
+    String numberOfProfilesText = notification.getFieldValue(NUMBER_OF_PROFILES);
+    checkState(numberOfProfilesText != null, "Could not read the built-in quality profile notification");
+    Integer numberOfProfiles = Integer.valueOf(numberOfProfilesText);
+    IntStream.rangeClosed(0, numberOfProfiles - 1)
+      .mapToObj(index -> new Profile(
+        requireNonNull(notification.getFieldValue(index + PROFILE_NAME)),
+        requireNonNull(notification.getFieldValue(index + LANGUAGE))))
+      .forEach(notif::addProfile);
+    return notif;
+  }
+
+  public List<Profile> getProfiles() {
+    return profiles;
+  }
+
+  public static class Profile {
+    private final String profileName;
+    private final String language;
+
+    public Profile(String profileName, String language) {
+      this.profileName = profileName;
+      this.language = language;
+    }
+
+    public String getProfileName() {
+      return profileName;
+    }
+
+    public String getLanguage() {
+      return language;
+    }
   }
 }
index 5fab56c976d7cb980fab32078a1b8f746e5fb340..49a688d2df71491f7d78153f539215bc6c5139b7 100644 (file)
@@ -26,7 +26,7 @@ import org.sonar.db.DbSession;
 import org.sonar.server.notification.NotificationDispatcher;
 import org.sonar.server.notification.email.EmailNotificationChannel;
 
-import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.BUILT_IN_QUALITY_PROFILES;
+import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationSender.BUILT_IN_QUALITY_PROFILES;
 
 public class BuiltInQualityProfilesNotificationDispatcher extends NotificationDispatcher {
 
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSender.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSender.java
new file mode 100644 (file)
index 0000000..329ad9d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.qualityprofile;
+
+import java.util.List;
+import org.sonar.api.resources.Languages;
+import org.sonar.server.notification.NotificationManager;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.Profile;
+
+public class BuiltInQualityProfilesNotificationSender {
+
+  static final String BUILT_IN_QUALITY_PROFILES = "built-in-quality-profiles";
+
+  private final NotificationManager notificationManager;
+  private final Languages languages;
+
+  public BuiltInQualityProfilesNotificationSender(NotificationManager notificationManager, Languages languages) {
+    this.notificationManager = notificationManager;
+    this.languages = languages;
+  }
+
+  void send(List<QProfileName> changedProfiles) {
+    BuiltInQualityProfilesNotification notification = new BuiltInQualityProfilesNotification();
+    changedProfiles.stream()
+      .map(changedProfile -> {
+        String profileName = changedProfile.getName();
+        String languageName = languages.get(changedProfile.getLanguage()).getName();
+        return new Profile(profileName, languageName);
+      })
+      .forEach(notification::addProfile);
+    notificationManager.scheduleForSending(notification.serialize());
+  }
+}
index b15c4f7046fbc2244dd6944c18188bc8313cb3f5..222525acfac0f14d8836f61aee2fb75db8a013ab 100644 (file)
  */
 package org.sonar.server.qualityprofile;
 
+import java.util.Comparator;
 import org.sonar.api.notifications.Notification;
 import org.sonar.plugins.emailnotifications.api.EmailMessage;
 import org.sonar.plugins.emailnotifications.api.EmailTemplate;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.Profile;
 
-import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.BUILT_IN_QUALITY_PROFILES;
+import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationSender.BUILT_IN_QUALITY_PROFILES;
 
 public class BuiltInQualityProfilesNotificationTemplate extends EmailTemplate {
 
@@ -32,11 +34,22 @@ public class BuiltInQualityProfilesNotificationTemplate extends EmailTemplate {
     if (!BUILT_IN_QUALITY_PROFILES.equals(notification.getType())) {
       return null;
     }
+
+    BuiltInQualityProfilesNotification profilesNotification = BuiltInQualityProfilesNotification.parse(notification);
+
+    StringBuilder message = new StringBuilder("Built-in quality profiles have been updated:\n");
+    profilesNotification.getProfiles().stream()
+      .sorted(Comparator.comparing(Profile::getLanguage).thenComparing(Profile::getProfileName))
+      .forEach(profile -> message.append("\"").append(profile.getProfileName()).append("\" - ").append(profile.getLanguage()).append("\n"));
+
+    message.append(
+      "This is a good time to review your quality profiles and update them to benefit from the latest evolutions.");
+
     // And finally return the email that will be sent
     return new EmailMessage()
       .setMessageId(BUILT_IN_QUALITY_PROFILES)
       .setSubject("empty")
-      .setMessage("This is a test message from SonarQube");
+      .setMessage(message.toString());
   }
 
 }
index 804876db07385ea7f6ebf54d1faa7b442e59a6f7..d343bbf526f4cd56fe45dcee4eaaf5a38e62d2c8 100644 (file)
@@ -46,11 +46,11 @@ public class RegisterQualityProfiles {
   private final DbClient dbClient;
   private final BuiltInQProfileInsert builtInQProfileInsert;
   private final BuiltInQProfileUpdate builtInQProfileUpdate;
-  private final BuiltInQualityProfilesNotification builtInQualityProfilesNotification;
+  private final BuiltInQualityProfilesNotificationSender builtInQualityProfilesNotification;
 
   public RegisterQualityProfiles(BuiltInQProfileRepository builtInQProfileRepository,
     DbClient dbClient, BuiltInQProfileInsert builtInQProfileInsert, BuiltInQProfileUpdate builtInQProfileUpdate,
-    BuiltInQualityProfilesNotification builtInQualityProfilesNotification) {
+    BuiltInQualityProfilesNotificationSender builtInQualityProfilesNotification) {
     this.builtInQProfileRepository = builtInQProfileRepository;
     this.dbClient = dbClient;
     this.builtInQProfileInsert = builtInQProfileInsert;
@@ -70,17 +70,20 @@ public class RegisterQualityProfiles {
 
       Map<QProfileName, RulesProfileDto> persistedRuleProfiles = loadPersistedProfiles(dbSession);
 
-      List<ActiveRuleChange> changes = new ArrayList<>();
+      List<QProfileName> changedProfiles = new ArrayList<>();
       builtInQProfiles.forEach(builtIn -> {
         RulesProfileDto ruleProfile = persistedRuleProfiles.get(builtIn.getQProfileName());
         if (ruleProfile == null) {
           register(dbSession, batchDbSession, builtIn);
         } else {
-          changes.addAll(update(dbSession, builtIn, ruleProfile));
+          List<ActiveRuleChange> changes = update(dbSession, builtIn, ruleProfile);
+          if (!changes.isEmpty()) {
+            changedProfiles.add(builtIn.getQProfileName());
+          }
         }
       });
-      if (!changes.isEmpty()) {
-        builtInQualityProfilesNotification.send();
+      if (!changedProfiles.isEmpty()) {
+        builtInQualityProfilesNotification.send(changedProfiles);
       }
     }
     profiler.stopDebug();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSenderTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSenderTest.java
new file mode 100644 (file)
index 0000000..8194128
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.qualityprofile;
+
+import java.util.List;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.notifications.Notification;
+import org.sonar.api.resources.Languages;
+import org.sonar.server.language.LanguageTesting;
+import org.sonar.server.notification.NotificationManager;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.Profile;
+
+import static java.util.Collections.singletonList;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Java6Assertions.assertThat;
+import static org.assertj.core.api.Java6Assertions.tuple;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class BuiltInQualityProfilesNotificationSenderTest {
+
+  private NotificationManager notificationManager = mock(NotificationManager.class);
+
+  @Test
+  public void add_profile_to_notification() throws Exception {
+    String profileName = randomLowerCaseText();
+    String languageKey = randomLowerCaseText();
+    String languageName = randomLowerCaseText();
+    List<QProfileName> profileNames = singletonList(new QProfileName(languageKey, profileName));
+    Languages languages = new Languages(LanguageTesting.newLanguage(languageKey, languageName));
+
+    BuiltInQualityProfilesNotificationSender underTest = new BuiltInQualityProfilesNotificationSender(notificationManager, languages);
+    underTest.send(profileNames);
+
+    ArgumentCaptor<Notification> notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class);
+    verify(notificationManager).scheduleForSending(notificationArgumentCaptor.capture());
+    verifyNoMoreInteractions(notificationManager);
+    assertThat(BuiltInQualityProfilesNotification.parse(notificationArgumentCaptor.getValue()).getProfiles())
+      .extracting(Profile::getProfileName, Profile::getLanguage)
+      .containsExactlyInAnyOrder(tuple(profileName, languageName));
+  }
+
+  private static String randomLowerCaseText() {
+    return randomAlphanumeric(20).toLowerCase();
+  }
+}
\ No newline at end of file
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplateTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplateTest.java
new file mode 100644 (file)
index 0000000..27a65ed
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.qualityprofile;
+
+import org.junit.Test;
+import org.sonar.plugins.emailnotifications.api.EmailMessage;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.Profile;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BuiltInQualityProfilesNotificationTemplateTest {
+
+  private BuiltInQualityProfilesNotificationTemplate underTest = new BuiltInQualityProfilesNotificationTemplate();
+
+  @Test
+  public void notification_contains_list_of_quality_profiles() {
+    String profileName = randomAlphanumeric(20);
+    String language = randomAlphanumeric(20);
+    BuiltInQualityProfilesNotification notification = new BuiltInQualityProfilesNotification()
+      .addProfile(new Profile(profileName, language));
+
+    EmailMessage emailMessage = underTest.format(notification.serialize());
+
+    assertThat(emailMessage.getMessage()).isEqualTo("Built-in quality profiles have been updated:\n" +
+      "\"" + profileName + "\" - " + language + "\n" +
+      "This is a good time to review your quality profiles and update them to benefit from the latest evolutions.");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTest.java
new file mode 100644 (file)
index 0000000..7ea0b93
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.qualityprofile;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.notifications.Notification;
+import org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.Profile;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationSender.BUILT_IN_QUALITY_PROFILES;
+
+public class BuiltInQualityProfilesNotificationTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  @Test
+  public void serialize_and_parse_no_profile() {
+    Notification notification = new BuiltInQualityProfilesNotification().serialize();
+
+    BuiltInQualityProfilesNotification result = BuiltInQualityProfilesNotification.parse(notification);
+
+    assertThat(result.getProfiles()).isEmpty();
+  }
+
+  @Test
+  public void serialize_and_parse_single_profile() {
+    String profileName = randomAlphanumeric(20);
+    String language = randomAlphanumeric(20);
+
+    Notification notification = new BuiltInQualityProfilesNotification().addProfile(new Profile(profileName, language)).serialize();
+    BuiltInQualityProfilesNotification result = BuiltInQualityProfilesNotification.parse(notification);
+
+    assertThat(result.getProfiles()).extracting(Profile::getProfileName, Profile::getLanguage)
+      .containsExactlyInAnyOrder(tuple(profileName, language));
+  }
+
+  @Test
+  public void serialize_and_parse_multiple_profiles() {
+    String profileName1 = randomAlphanumeric(20);
+    String language1 = randomAlphanumeric(20);
+    String profileName2 = randomAlphanumeric(20);
+    String language2 = randomAlphanumeric(20);
+
+    Notification notification = new BuiltInQualityProfilesNotification()
+      .addProfile(new Profile(profileName1, language1))
+      .addProfile(new Profile(profileName2, language2))
+      .serialize();
+    BuiltInQualityProfilesNotification result = BuiltInQualityProfilesNotification.parse(notification);
+
+    assertThat(result.getProfiles()).extracting(Profile::getProfileName, Profile::getLanguage)
+      .containsExactlyInAnyOrder(tuple(profileName1, language1), tuple(profileName2, language2));
+  }
+
+  @Test
+  public void fail_with_ISE_when_parsing_empty_notification() {
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Could not read the built-in quality profile notification");
+
+    BuiltInQualityProfilesNotification.parse(new Notification(BUILT_IN_QUALITY_PROFILES));
+  }
+}
index 4c2c71cf4d7ee86be68c1ce8730ac00370e9f349..362486e0fec56bd59689e2cc3aa356399cd29ccd 100644 (file)
 package org.sonar.server.qualityprofile;
 
 import java.util.Arrays;
+import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.rules.ActiveRule;
 import org.sonar.api.rules.RulePriority;
@@ -42,6 +44,8 @@ import org.sonar.server.util.TypeValidations;
 
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.apache.commons.lang.math.RandomUtils.nextLong;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
@@ -71,7 +75,7 @@ public class RegisterQualityProfilesNotificationTest {
   private RuleActivator ruleActivator = new RuleActivator(system2, dbClient, mock(RuleIndex.class), new RuleActivatorContextFactory(dbClient), typeValidations, activeRuleIndexer,
     userSessionRule);
   private BuiltInQProfileUpdate builtInQProfileUpdate = new BuiltInQProfileUpdateImpl(dbClient, ruleActivator, activeRuleIndexer);
-  private BuiltInQualityProfilesNotification builtInQualityProfilesNotification = mock(BuiltInQualityProfilesNotification.class);
+  private BuiltInQualityProfilesNotificationSender builtInQualityProfilesNotification = mock(BuiltInQualityProfilesNotificationSender.class);
   private RegisterQualityProfiles underTest = new RegisterQualityProfiles(builtInQProfileRepositoryRule, dbClient,
     builtInQProfileInsert, builtInQProfileUpdate, builtInQualityProfilesNotification);
 
@@ -112,7 +116,12 @@ public class RegisterQualityProfilesNotificationTest {
 
     underTest.start();
 
-    verify(builtInQualityProfilesNotification).send();
+    ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+    verify(builtInQualityProfilesNotification).send(captor.capture());
+    List<QProfileName> updatedProfiles = captor.<List<QProfileName>>getValue();
+    assertThat(updatedProfiles)
+      .extracting(QProfileName::getName, QProfileName::getLanguage)
+      .containsExactlyInAnyOrder(tuple(dbProfile.getName(), dbProfile.getLanguage()));
   }
 
   @Test
@@ -132,7 +141,15 @@ public class RegisterQualityProfilesNotificationTest {
 
     underTest.start();
 
-    verify(builtInQualityProfilesNotification).send();
+    ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+    verify(builtInQualityProfilesNotification).send(captor.capture());
+    List<QProfileName> updatedProfiles = captor.<List<QProfileName>>getValue();
+    assertThat(updatedProfiles)
+      .extracting(QProfileName::getName, QProfileName::getLanguage)
+      .containsExactlyInAnyOrder(
+        tuple(dbProfile1.getName(), dbProfile1.getLanguage()),
+        tuple(dbProfile2.getName(), dbProfile2.getLanguage())
+      );
   }
 
   private void addPluginProfile(RulesProfileDto dbProfile, RuleDefinitionDto... dbRules) {
index 3600b290b6ae42554240e404be34b5f9fa6e7d3a..5b290ec06cb4ab9c571158b4f4dfb6bd46fbc908 100644 (file)
@@ -60,7 +60,7 @@ public class RegisterQualityProfilesTest {
   private DbClient dbClient = db.getDbClient();
   private DummyBuiltInQProfileInsert insert = new DummyBuiltInQProfileInsert();
   private DummyBuiltInQProfileUpdate update = new DummyBuiltInQProfileUpdate();
-  private RegisterQualityProfiles underTest = new RegisterQualityProfiles(builtInQProfileRepositoryRule, dbClient, insert, update, mock(BuiltInQualityProfilesNotification.class));
+  private RegisterQualityProfiles underTest = new RegisterQualityProfiles(builtInQProfileRepositoryRule, dbClient, insert, update, mock(BuiltInQualityProfilesNotificationSender.class));
 
   @Test
   public void start_fails_if_BuiltInQProfileRepository_has_not_been_initialized() {
index 522bc81483d0891c8b1f0c400a321d955bd480b8..a2b2d237b01f8cfc651eb0f787fd216ed9cc7edf 100644 (file)
@@ -24,7 +24,7 @@ import org.sonar.api.resources.Language;
 public class Foo implements Language {
 
   public static final String KEY = "foo";
-  public static final String NAME = "foo";
+  public static final String NAME = "Foo";
 
   @Override
   public String getKey() {
index 522bc81483d0891c8b1f0c400a321d955bd480b8..a2b2d237b01f8cfc651eb0f787fd216ed9cc7edf 100644 (file)
@@ -24,7 +24,7 @@ import org.sonar.api.resources.Language;
 public class Foo implements Language {
 
   public static final String KEY = "foo";
-  public static final String NAME = "foo";
+  public static final String NAME = "Foo";
 
   @Override
   public String getKey() {
index 9960e8b7c4229f4cfe96634ebf0ab5a557c65bdf..4f287380171e49a59c3fe30114617592be52a15a 100644 (file)
@@ -22,6 +22,7 @@ package org.sonarqube.tests.qualityProfile;
 
 import com.sonar.orchestrator.Orchestrator;
 import java.io.File;
+import java.util.List;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 import org.junit.After;
@@ -129,15 +130,17 @@ public class BuiltInQualityProfilesNotificationTest {
     orchestrator.restartServer();
 
     waitUntilAllNotificationsAreDelivered(2, 10, 1_000);
-    assertThat(smtpServer.getMessages())
+    List<WiserMessage> messages = smtpServer.getMessages();
+    assertThat(messages)
       .extracting(this::getMimeMessage)
       .extracting(this::getAllRecipients)
       .containsOnly("<" + profileAdmin1.getEmail() + ">", "<" + profileAdmin2.getEmail() + ">");
-    assertThat(smtpServer.getMessages())
-      .extracting(this::getMimeMessage)
-      .extracting(this::getContent)
-      .extracting(m -> m.contains("This is a test message from SonarQube"))
-      .containsOnly(true);
+    assertThat(messages.get(0).getMimeMessage().getContent().toString())
+      .containsSequence(
+        "Built-in quality profiles have been updated:",
+        "\"Basic\" - Foo",
+        "This is a good time to review your quality profiles and update them to benefit from the latest evolutions.")
+      .isEqualTo(messages.get(1).getMimeMessage().getContent().toString());
   }
 
   private MimeMessage getMimeMessage(WiserMessage msg) {