From e5eb765a319edacb43ab7cfa5714659deb1fcad0 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 20 Jun 2017 15:38:20 +0200 Subject: [PATCH] SONAR-9442 add names of changed quality profiles in mail notification --- .../src/main/java/org/sonar/foo/Foo.java | 2 +- .../src/main/java/org/sonar/foo/Foo.java | 2 +- .../platformlevel/PlatformLevelStartup.java | 4 +- .../BuiltInQualityProfilesNotification.java | 70 ++++++++++++++-- ...QualityProfilesNotificationDispatcher.java | 2 +- ...ltInQualityProfilesNotificationSender.java | 51 +++++++++++ ...InQualityProfilesNotificationTemplate.java | 17 +++- .../RegisterQualityProfiles.java | 15 ++-- ...QualityProfilesNotificationSenderTest.java | 65 ++++++++++++++ ...alityProfilesNotificationTemplateTest.java | 47 +++++++++++ ...uiltInQualityProfilesNotificationTest.java | 84 +++++++++++++++++++ ...gisterQualityProfilesNotificationTest.java | 23 ++++- .../RegisterQualityProfilesTest.java | 2 +- .../src/main/java/org/sonar/foo/Foo.java | 2 +- .../src/main/java/org/sonar/foo/Foo.java | 2 +- ...uiltInQualityProfilesNotificationTest.java | 15 ++-- 16 files changed, 369 insertions(+), 34 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSender.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSenderTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplateTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTest.java diff --git a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java index 522bc81483d..a2b2d237b01 100644 --- a/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java +++ b/it/it-plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java @@ -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() { diff --git a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java index 522bc81483d..a2b2d237b01 100644 --- a/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java +++ b/it/it-plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java @@ -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() { diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java index 39c20db53c7..7c6e83e469f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevelStartup.java @@ -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, diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java index cdc2b657748..9c2a906147c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotification.java @@ -20,22 +20,74 @@ 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 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 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; + } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java index 5fab56c976d..49a688d2df7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationDispatcher.java @@ -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 index 00000000000..329ad9da3cc --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSender.java @@ -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 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()); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java index b15c4f7046f..222525acfac 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplate.java @@ -19,11 +19,13 @@ */ 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()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java index 804876db073..d343bbf526f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java @@ -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 persistedRuleProfiles = loadPersistedProfiles(dbSession); - List changes = new ArrayList<>(); + List 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 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 index 00000000000..819412888d5 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationSenderTest.java @@ -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 profileNames = singletonList(new QProfileName(languageKey, profileName)); + Languages languages = new Languages(LanguageTesting.newLanguage(languageKey, languageName)); + + BuiltInQualityProfilesNotificationSender underTest = new BuiltInQualityProfilesNotificationSender(notificationManager, languages); + underTest.send(profileNames); + + ArgumentCaptor 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 index 00000000000..27a65edfb2b --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTemplateTest.java @@ -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 index 00000000000..7ea0b93b029 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQualityProfilesNotificationTest.java @@ -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)); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java index 4c2c71cf4d7..362486e0fec 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java @@ -20,9 +20,11 @@ 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 captor = ArgumentCaptor.forClass(List.class); + verify(builtInQualityProfilesNotification).send(captor.capture()); + List updatedProfiles = captor.>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 captor = ArgumentCaptor.forClass(List.class); + verify(builtInQualityProfilesNotification).send(captor.capture()); + List updatedProfiles = captor.>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) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java index 3600b290b6a..5b290ec06cb 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesTest.java @@ -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() { diff --git a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java index 522bc81483d..a2b2d237b01 100644 --- a/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java +++ b/tests/plugins/foo-plugin-v1/src/main/java/org/sonar/foo/Foo.java @@ -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() { diff --git a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java index 522bc81483d..a2b2d237b01 100644 --- a/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java +++ b/tests/plugins/foo-plugin-v2/src/main/java/org/sonar/foo/Foo.java @@ -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() { diff --git a/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java b/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java index 9960e8b7c42..4f287380171 100644 --- a/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java +++ b/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java @@ -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 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) { -- 2.39.5