From: Julien Lancelot Date: Thu, 22 Jun 2017 14:20:05 +0000 (+0200) Subject: SONAR-9442 filter changelog by dates in quality profile notification X-Git-Tag: 6.5-M2~67 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b9a26d0024cf19e19b644c81e4ba422d9b47e509;p=sonarqube.git SONAR-9442 filter changelog by dates in quality profile notification --- 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 fe2c0ddc6eb..e128416726a 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 @@ -28,6 +28,7 @@ import org.sonar.api.notifications.Notification; import static com.google.common.base.Preconditions.checkState; import static java.lang.Integer.parseInt; +import static java.lang.Long.parseLong; import static java.lang.String.format; import static java.util.Objects.requireNonNull; import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationSender.BUILT_IN_QUALITY_PROFILES; @@ -41,6 +42,8 @@ public class BuiltInQualityProfilesNotification { private static final String NEW_RULES = ".newRules"; private static final String UPDATED_RULES = ".updatedRules"; private static final String REMOVED_RULES = ".removedRules"; + private static final String START_DATE = ".startDate"; + private static final String END_DATE = ".endDate"; private final List profiles = new ArrayList<>(); @@ -61,6 +64,8 @@ public class BuiltInQualityProfilesNotification { notification.setFieldValue(index + NEW_RULES, String.valueOf(profile.getNewRules())); notification.setFieldValue(index + UPDATED_RULES, String.valueOf(profile.getUpdatedRules())); notification.setFieldValue(index + REMOVED_RULES, String.valueOf(profile.getRemovedRules())); + notification.setFieldValue(index + START_DATE, String.valueOf(profile.getStartDate())); + notification.setFieldValue(index + END_DATE, String.valueOf(profile.getEndDate())); }); return notification; } @@ -80,6 +85,8 @@ public class BuiltInQualityProfilesNotification { .setNewRules(parseInt(getNonNullFieldValue(notification, index + NEW_RULES))) .setUpdatedRules(parseInt(getNonNullFieldValue(notification, index + UPDATED_RULES))) .setRemovedRules(parseInt(getNonNullFieldValue(notification, index + REMOVED_RULES))) + .setStartDate(parseLong(getNonNullFieldValue(notification, index + START_DATE))) + .setEndDate(parseLong(getNonNullFieldValue(notification, index + END_DATE))) .build()) .forEach(notif::addProfile); return notif; @@ -101,6 +108,8 @@ public class BuiltInQualityProfilesNotification { private final int newRules; private final int updatedRules; private final int removedRules; + private final long startDate; + private final long endDate; public Profile(Builder builder) { this.profileName = builder.profileName; @@ -109,6 +118,8 @@ public class BuiltInQualityProfilesNotification { this.newRules = builder.newRules; this.updatedRules = builder.updatedRules; this.removedRules = builder.removedRules; + this.startDate = builder.startDate; + this.endDate = builder.endDate; } public String getProfileName() { @@ -135,6 +146,14 @@ public class BuiltInQualityProfilesNotification { return removedRules; } + public long getStartDate() { + return startDate; + } + + public long getEndDate() { + return endDate; + } + public static Builder newBuilder() { return new Builder(); } @@ -146,6 +165,8 @@ public class BuiltInQualityProfilesNotification { private int newRules; private int updatedRules; private int removedRules; + private long startDate; + private long endDate; private Builder() { } @@ -183,6 +204,16 @@ public class BuiltInQualityProfilesNotification { return this; } + public Builder setStartDate(long startDate) { + this.startDate = startDate; + return this; + } + + public Builder setEndDate(long endDate) { + this.endDate = endDate; + return this; + } + public Profile build() { return new Profile(this); } 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 index 9ed6c7c150a..4e7dc8aa21f 100644 --- 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 @@ -43,7 +43,7 @@ public class BuiltInQualityProfilesNotificationSender { this.languages = languages; } - void send(Multimap changedProfiles) { + void send(Multimap changedProfiles, long startDate, long endDate) { BuiltInQualityProfilesNotification notification = new BuiltInQualityProfilesNotification(); changedProfiles.keySet().stream() .map(changedProfile -> { @@ -60,6 +60,8 @@ public class BuiltInQualityProfilesNotificationSender { .setNewRules(newRules) .setUpdatedRules(updatedRules) .setRemovedRules(removedRules) + .setStartDate(startDate) + .setEndDate(endDate) .build(); }) .forEach(notification::addProfile); 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 d26f07fc8e0..c03fa96486f 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 @@ -23,11 +23,13 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Comparator; +import java.util.Date; import org.sonar.api.notifications.Notification; import org.sonar.api.platform.Server; import org.sonar.plugins.emailnotifications.api.EmailMessage; import org.sonar.plugins.emailnotifications.api.EmailTemplate; +import static org.sonar.api.utils.DateUtils.formatDate; import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.Profile; import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification.parse; import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotificationSender.BUILT_IN_QUALITY_PROFILES; @@ -61,6 +63,10 @@ public class BuiltInQualityProfilesNotificationTemplate extends EmailTemplate { .append(profile.getLanguageKey()) .append("&name=") .append(encode(profile.getProfileName())) + .append("&since=") + .append(formatDate(new Date(profile.getStartDate()))) + .append("&to=") + .append(formatDate(new Date(profile.getEndDate()))) .append("\n"); int newRules = profile.getNewRules(); if (newRules > 0) { 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 0f15106cacd..ecc84b98c43 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 @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import org.sonar.api.server.ServerSide; +import org.sonar.api.utils.System2; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; @@ -49,15 +50,17 @@ public class RegisterQualityProfiles { private final BuiltInQProfileInsert builtInQProfileInsert; private final BuiltInQProfileUpdate builtInQProfileUpdate; private final BuiltInQualityProfilesNotificationSender builtInQualityProfilesNotification; + private final System2 system2; public RegisterQualityProfiles(BuiltInQProfileRepository builtInQProfileRepository, - DbClient dbClient, BuiltInQProfileInsert builtInQProfileInsert, BuiltInQProfileUpdate builtInQProfileUpdate, - BuiltInQualityProfilesNotificationSender builtInQualityProfilesNotification) { + DbClient dbClient, BuiltInQProfileInsert builtInQProfileInsert, BuiltInQProfileUpdate builtInQProfileUpdate, + BuiltInQualityProfilesNotificationSender builtInQualityProfilesNotification, System2 system2) { this.builtInQProfileRepository = builtInQProfileRepository; this.dbClient = dbClient; this.builtInQProfileInsert = builtInQProfileInsert; this.builtInQProfileUpdate = builtInQProfileUpdate; this.builtInQualityProfilesNotification = builtInQualityProfilesNotification; + this.system2 = system2; } public void start() { @@ -69,6 +72,7 @@ public class RegisterQualityProfiles { Profiler profiler = Profiler.create(Loggers.get(getClass())).startInfo("Register quality profiles"); try (DbSession dbSession = dbClient.openSession(false); DbSession batchDbSession = dbClient.openSession(true)) { + long startDate = system2.now(); Map persistedRuleProfiles = loadPersistedProfiles(dbSession); @@ -85,7 +89,8 @@ public class RegisterQualityProfiles { } }); if (!changedProfiles.isEmpty()) { - builtInQualityProfilesNotification.send(changedProfiles); + long endDate = system2.now(); + builtInQualityProfilesNotification.send(changedProfiles, startDate, endDate); } } 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 index cdca660efc4..78444c9124b 100644 --- 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 @@ -57,7 +57,7 @@ public class BuiltInQualityProfilesNotificationSenderTest { Tuple expectedTuple = addProfile(profiles, languages, ACTIVATED); BuiltInQualityProfilesNotificationSender underTest = new BuiltInQualityProfilesNotificationSender(notificationManager, languages); - underTest.send(profiles); + underTest.send(profiles, 0, 1); ArgumentCaptor notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); verify(notificationManager).scheduleForSending(notificationArgumentCaptor.capture()); @@ -74,7 +74,7 @@ public class BuiltInQualityProfilesNotificationSenderTest { Tuple expectedTuple = addProfile(profiles, languages, UPDATED); BuiltInQualityProfilesNotificationSender underTest = new BuiltInQualityProfilesNotificationSender(notificationManager, languages); - underTest.send(profiles); + underTest.send(profiles, 0, 1); ArgumentCaptor notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); verify(notificationManager).scheduleForSending(notificationArgumentCaptor.capture()); @@ -91,7 +91,7 @@ public class BuiltInQualityProfilesNotificationSenderTest { Tuple expectedTuple = addProfile(profiles, languages, DEACTIVATED); BuiltInQualityProfilesNotificationSender underTest = new BuiltInQualityProfilesNotificationSender(notificationManager, languages); - underTest.send(profiles); + underTest.send(profiles, 0, 1); ArgumentCaptor notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); verify(notificationManager).scheduleForSending(notificationArgumentCaptor.capture()); @@ -109,7 +109,7 @@ public class BuiltInQualityProfilesNotificationSenderTest { Tuple expectedTuple2 = addProfile(profiles, languages, ACTIVATED); BuiltInQualityProfilesNotificationSender underTest = new BuiltInQualityProfilesNotificationSender(notificationManager, languages); - underTest.send(profiles); + underTest.send(profiles, 0, 1); ArgumentCaptor notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); verify(notificationManager).scheduleForSending(notificationArgumentCaptor.capture()); @@ -119,6 +119,25 @@ public class BuiltInQualityProfilesNotificationSenderTest { .containsExactlyInAnyOrder(expectedTuple1, expectedTuple2); } + @Test + public void add_start_and_end_dates_to_notification() throws Exception { + Multimap profiles = ArrayListMultimap.create(); + Languages languages = new Languages(); + addProfile(profiles, languages, ACTIVATED); + long startDate = RANDOM.nextInt(5000); + long endDate = startDate + RANDOM.nextInt(5000); + + BuiltInQualityProfilesNotificationSender underTest = new BuiltInQualityProfilesNotificationSender(notificationManager, languages); + underTest.send(profiles, startDate, endDate); + + ArgumentCaptor notificationArgumentCaptor = ArgumentCaptor.forClass(Notification.class); + verify(notificationManager).scheduleForSending(notificationArgumentCaptor.capture()); + verifyNoMoreInteractions(notificationManager); + assertThat(BuiltInQualityProfilesNotification.parse(notificationArgumentCaptor.getValue()).getProfiles()) + .extracting(Profile::getStartDate, Profile::getEndDate) + .containsExactlyInAnyOrder(tuple(startDate, endDate)); + } + private Tuple addProfile(Multimap profiles, Languages languages, ActiveRuleChange.Type type) { String profileName = randomLowerCaseText(); Language language = newLanguage(randomLowerCaseText(), randomLowerCaseText()); 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 index b7d055214d7..8cfdfc97f51 100644 --- 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 @@ -20,6 +20,7 @@ package org.sonar.server.qualityprofile; +import java.util.Date; import org.junit.Before; import org.junit.Test; import org.sonar.api.platform.Server; @@ -30,6 +31,7 @@ import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.sonar.api.utils.DateUtils.formatDate; public class BuiltInQualityProfilesNotificationTemplateTest { @@ -58,8 +60,7 @@ public class BuiltInQualityProfilesNotificationTemplateTest { EmailMessage emailMessage = underTest.format(notification.serialize()); assertMessage(emailMessage, - profileTitleText(profileName, languageKey, languageName) + - " 2 new rules\n"); + "\n 2 new rules\n"); } @Test @@ -78,7 +79,7 @@ public class BuiltInQualityProfilesNotificationTemplateTest { EmailMessage emailMessage = underTest.format(notification.serialize()); assertMessage(emailMessage, - profileTitleText(profileName, languageKey, languageName) + + "\n" + " 2 rules have been updated\n"); } @@ -98,7 +99,7 @@ public class BuiltInQualityProfilesNotificationTemplateTest { EmailMessage emailMessage = underTest.format(notification.serialize()); assertMessage(emailMessage, - profileTitleText(profileName, languageKey, languageName) + + "\n" + " 2 rules removed\n"); } @@ -120,7 +121,7 @@ public class BuiltInQualityProfilesNotificationTemplateTest { EmailMessage emailMessage = underTest.format(notification.serialize()); assertMessage(emailMessage, - profileTitleText(profileName, languageKey, languageName) + + "\n" + " 2 new rules\n" + " 3 rules have been updated\n" + " 4 rules removed\n"); @@ -150,11 +151,12 @@ public class BuiltInQualityProfilesNotificationTemplateTest { EmailMessage emailMessage = underTest.format(notification.serialize()); - assertMessage(emailMessage, - profileTitleText(profileName1, languageKey1, languageName1) + - " 2 new rules\n" + - profileTitleText(profileName2, languageKey2, languageName2) + - " 13 new rules\n"); + assertThat(emailMessage.getMessage()).containsSequence("Built-in quality profiles have been updated:\n", + profileTitleText(profileName1, languageKey1, languageName1), + " 2 new rules\n", + profileTitleText(profileName2, languageKey2, languageName2), + " 13 new rules\n", + "This is a good time to review your quality profiles and update them to benefit from the latest evolutions. " + server.getPublicRootUrl() + "/profiles"); } @Test @@ -193,15 +195,41 @@ public class BuiltInQualityProfilesNotificationTemplateTest { assertThat(emailMessage.getMessage()).contains(server.getPublicRootUrl() + "/profiles/changelog?language=java&name=Sonar+Way"); } + @Test + public void notification_contains_from_and_to_date() { + String profileName = newProfileName(); + String languageKey = newLanguageKey(); + String languageName = newLanguageName(); + long startDate = 1_000_000_000_000L; + long endDate = startDate + 1_100_000_000_000L; + BuiltInQualityProfilesNotification notification = new BuiltInQualityProfilesNotification() + .addProfile(Profile.newBuilder() + .setProfileName(profileName) + .setLanguageKey(languageKey) + .setLanguageName(languageName) + .setStartDate(startDate) + .setEndDate(endDate) + .build()); + + EmailMessage emailMessage = underTest.format(notification.serialize()); + + assertMessage(emailMessage, + profileTitleText(profileName, languageKey, languageName, formatDate(new Date(startDate)), formatDate(new Date(endDate)))); + } + private void assertMessage(EmailMessage emailMessage, String expectedProfileDetails) { - String expected = "Built-in quality profiles have been updated:\n" + - expectedProfileDetails + - "This is a good time to review your quality profiles and update them to benefit from the latest evolutions. " + server.getPublicRootUrl() + "/profiles"; - assertThat(emailMessage.getMessage()).isEqualTo(expected); + assertThat(emailMessage.getMessage()).containsSequence("Built-in quality profiles have been updated:\n", + expectedProfileDetails, + "This is a good time to review your quality profiles and update them to benefit from the latest evolutions. " + server.getPublicRootUrl() + "/profiles"); } private String profileTitleText(String profileName, String languageKey, String languageName) { - return "\"" + profileName + "\" - " + languageName + " " + server.getPublicRootUrl() + "/profiles/changelog?language=" + languageKey + "&name=" + profileName + "\n"; + return "\"" + profileName + "\" - " + languageName + " " + server.getPublicRootUrl() + "/profiles/changelog?language=" + languageKey + "&name=" + profileName; + } + + private String profileTitleText(String profileName, String languageKey, String languageName, String startDate, String endDate) { + return "\"" + profileName + "\" - " + languageName + " " + server.getPublicRootUrl() + "/profiles/changelog?language=" + languageKey + "&name=" + profileName + + "&since=" + startDate + "&to=" + endDate + "\n"; } private static String newProfileName() { 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 index bacbaa97af5..01c62edbfa1 100644 --- 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 @@ -20,6 +20,7 @@ package org.sonar.server.qualityprofile; +import java.util.Random; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -33,6 +34,8 @@ import static org.sonar.server.qualityprofile.BuiltInQualityProfilesNotification public class BuiltInQualityProfilesNotificationTest { + private static final Random RANDOM = new Random(); + @Rule public ExpectedException expectedException = ExpectedException.none(); @@ -50,22 +53,30 @@ public class BuiltInQualityProfilesNotificationTest { String profileName = randomAlphanumeric(20); String languageKey = randomAlphanumeric(20); String languageName = randomAlphanumeric(20); + int newRules = RANDOM.nextInt(5000); + int updatedRules = RANDOM.nextInt(5000); + int removedRules = RANDOM.nextInt(5000); + long startDate = RANDOM.nextInt(5000); + long endDate = startDate + RANDOM.nextInt(5000); Notification notification = new BuiltInQualityProfilesNotification() .addProfile(Profile.newBuilder() .setProfileName(profileName) .setLanguageKey(languageKey) .setLanguageName(languageName) - .setNewRules(3) - .setUpdatedRules(5) - .setRemovedRules(7) + .setNewRules(newRules) + .setUpdatedRules(updatedRules) + .setRemovedRules(removedRules) + .setStartDate(startDate) + .setEndDate(endDate) .build()) .serialize(); BuiltInQualityProfilesNotification result = BuiltInQualityProfilesNotification.parse(notification); - assertThat(result.getProfiles()).extracting(Profile::getProfileName, Profile::getLanguageKey, Profile::getLanguageName, - Profile::getNewRules, Profile::getUpdatedRules, Profile::getRemovedRules) - .containsExactlyInAnyOrder(tuple(profileName, languageKey, languageName, 3, 5, 7)); + assertThat(result.getProfiles()) + .extracting(Profile::getProfileName, Profile::getLanguageKey, Profile::getLanguageName, Profile::getNewRules, Profile::getUpdatedRules, Profile::getRemovedRules, + Profile::getStartDate, Profile::getEndDate) + .containsExactlyInAnyOrder(tuple(profileName, languageKey, languageName, newRules, updatedRules, removedRules, startDate, endDate)); } @Test @@ -95,6 +106,37 @@ public class BuiltInQualityProfilesNotificationTest { .containsExactlyInAnyOrder(tuple(profileName1, languageKey1, languageName1), tuple(profileName2, languageKey2, languageName2)); } + @Test + public void serialize_and_parse_max_values() { + String profileName = randomAlphanumeric(20); + String languageKey = randomAlphanumeric(20); + String languageName = randomAlphanumeric(20); + int newRules = Integer.MAX_VALUE; + int updatedRules = Integer.MAX_VALUE; + int removedRules = Integer.MAX_VALUE; + long startDate = Long.MAX_VALUE; + long endDate = Long.MAX_VALUE; + + Notification notification = new BuiltInQualityProfilesNotification() + .addProfile(Profile.newBuilder() + .setProfileName(profileName) + .setLanguageKey(languageKey) + .setLanguageName(languageName) + .setNewRules(newRules) + .setUpdatedRules(updatedRules) + .setRemovedRules(removedRules) + .setStartDate(startDate) + .setEndDate(endDate) + .build()) + .serialize(); + BuiltInQualityProfilesNotification result = BuiltInQualityProfilesNotification.parse(notification); + + assertThat(result.getProfiles()) + .extracting(Profile::getProfileName, Profile::getLanguageKey, Profile::getLanguageName, Profile::getNewRules, Profile::getUpdatedRules, Profile::getRemovedRules, + Profile::getStartDate, Profile::getEndDate) + .containsExactlyInAnyOrder(tuple(profileName, languageKey, languageName, newRules, updatedRules, removedRules, startDate, endDate)); + } + @Test public void fail_with_ISE_when_parsing_empty_notification() { expectedException.expect(IllegalStateException.class); 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 2bbfb98a9e2..4cb10e90b81 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 @@ -21,6 +21,7 @@ package org.sonar.server.qualityprofile; import com.google.common.collect.Multimap; import java.util.Arrays; +import java.util.Random; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -29,7 +30,6 @@ import org.sonar.api.profiles.RulesProfile; import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.RulePriority; import org.sonar.api.utils.System2; -import org.sonar.api.utils.internal.AlwaysIncreasingSystem2; import org.sonar.api.utils.log.LogTester; import org.sonar.core.util.UuidFactoryFast; import org.sonar.db.DbClient; @@ -48,9 +48,13 @@ 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.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; import static org.sonar.api.rules.Rule.create; import static org.sonar.api.rules.RulePriority.MAJOR; import static org.sonar.db.qualityprofile.QualityProfileTesting.newRuleProfileDto; @@ -60,7 +64,9 @@ import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.DEACTIVATED; public class RegisterQualityProfilesNotificationTest { - private System2 system2 = new AlwaysIncreasingSystem2(); + private static final Random RANDOM = new Random(); + + private System2 system2 = mock(System2.class); @Rule public DbTester db = DbTester.create(system2); @Rule @@ -69,9 +75,9 @@ public class RegisterQualityProfilesNotificationTest { public ExpectedException expectedException = ExpectedException.none(); @Rule public BuiltInQProfileRepositoryRule builtInQProfileRepositoryRule = new BuiltInQProfileRepositoryRule(); + @Rule public LogTester logTester = new LogTester(); - private DbClient dbClient = db.getDbClient(); private TypeValidations typeValidations = mock(TypeValidations.class); private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class); @@ -81,7 +87,7 @@ public class RegisterQualityProfilesNotificationTest { private BuiltInQProfileUpdate builtInQProfileUpdate = new BuiltInQProfileUpdateImpl(dbClient, ruleActivator, activeRuleIndexer); private BuiltInQualityProfilesNotificationSender builtInQualityProfilesNotification = mock(BuiltInQualityProfilesNotificationSender.class); private RegisterQualityProfiles underTest = new RegisterQualityProfiles(builtInQProfileRepositoryRule, dbClient, - builtInQProfileInsert, builtInQProfileUpdate, builtInQualityProfilesNotification); + builtInQProfileInsert, builtInQProfileUpdate, builtInQualityProfilesNotification, system2); @Test public void does_not_send_notification_on_new_profile() { @@ -121,7 +127,7 @@ public class RegisterQualityProfilesNotificationTest { underTest.start(); ArgumentCaptor captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).send(captor.capture()); + verify(builtInQualityProfilesNotification).send(captor.capture(), anyLong(), anyLong()); Multimap updatedProfiles = captor.>getValue(); assertThat(updatedProfiles.keySet()) .extracting(QProfileName::getName, QProfileName::getLanguage) @@ -143,7 +149,7 @@ public class RegisterQualityProfilesNotificationTest { underTest.start(); ArgumentCaptor captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).send(captor.capture()); + verify(builtInQualityProfilesNotification).send(captor.capture(), anyLong(), anyLong()); Multimap updatedProfiles = captor.>getValue(); assertThat(updatedProfiles.keySet()) .extracting(QProfileName::getName, QProfileName::getLanguage) @@ -173,7 +179,7 @@ public class RegisterQualityProfilesNotificationTest { underTest.start(); ArgumentCaptor captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).send(captor.capture()); + verify(builtInQualityProfilesNotification).send(captor.capture(), anyLong(), anyLong()); Multimap updatedProfiles = captor.>getValue(); assertThat(updatedProfiles.keySet()) .extracting(QProfileName::getName, QProfileName::getLanguage) @@ -207,7 +213,7 @@ public class RegisterQualityProfilesNotificationTest { underTest.start(); ArgumentCaptor captor = ArgumentCaptor.forClass(Multimap.class); - verify(builtInQualityProfilesNotification).send(captor.capture()); + verify(builtInQualityProfilesNotification).send(captor.capture(), anyLong(), anyLong()); Multimap updatedProfiles = captor.>getValue(); assertThat(updatedProfiles.keySet()) .extracting(QProfileName::getName, QProfileName::getLanguage) @@ -217,6 +223,23 @@ public class RegisterQualityProfilesNotificationTest { .containsExactlyInAnyOrder(tuple(newRule.getId(), ACTIVATED)); } + @Test + public void send_start_and_end_date() { + String language = newLanguageKey(); + RuleDefinitionDto existingRule = db.rules().insert(r -> r.setLanguage(language)); + RulesProfileDto dbProfile = insertBuiltInProfile(language); + activateRuleInDb(dbProfile, existingRule, MAJOR); + RuleDefinitionDto newRule = db.rules().insert(r -> r.setLanguage(language)); + addPluginProfile(dbProfile, existingRule, newRule); + builtInQProfileRepositoryRule.initialize(); + long startDate = RANDOM.nextInt(5000); + long endDate = startDate + RANDOM.nextInt(5000); + when(system2.now()).thenReturn(startDate, endDate); + + underTest.start(); + + verify(builtInQualityProfilesNotification).send(any(), eq(startDate), eq(endDate)); + } private void addPluginProfile(RulesProfileDto dbProfile, RuleDefinitionDto... dbRules) { RulesProfile pluginProfile = RulesProfile.create(dbProfile.getName(), dbProfile.getLanguage()); 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 5b290ec06cb..5ad349cbfa9 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 @@ -26,6 +26,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.resources.Language; +import org.sonar.api.utils.System2; import org.sonar.api.utils.internal.AlwaysIncreasingSystem2; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; @@ -46,8 +47,9 @@ public class RegisterQualityProfilesTest { private static final Language FOO_LANGUAGE = LanguageTesting.newLanguage("foo"); private static final Language BAR_LANGUAGE = LanguageTesting.newLanguage("bar"); + private System2 system2 = new AlwaysIncreasingSystem2(); @Rule - public DbTester db = DbTester.create(new AlwaysIncreasingSystem2()); + public DbTester db = DbTester.create(system2); @Rule public UserSessionRule userSessionRule = UserSessionRule.standalone(); @Rule @@ -60,7 +62,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(BuiltInQualityProfilesNotificationSender.class)); + private RegisterQualityProfiles underTest = new RegisterQualityProfiles(builtInQProfileRepositoryRule, dbClient, insert, update, mock(BuiltInQualityProfilesNotificationSender.class), system2); @Test public void start_fails_if_BuiltInQProfileRepository_has_not_been_initialized() { 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 82aecb351c5..c2f2e343564 100644 --- a/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java +++ b/tests/src/test/java/org/sonarqube/tests/qualityProfile/BuiltInQualityProfilesNotificationTest.java @@ -139,7 +139,7 @@ public class BuiltInQualityProfilesNotificationTest { assertThat(messages.get(0).getMimeMessage().getContent().toString()) .containsSequence( "Built-in quality profiles have been updated:", - "\"Basic\" - Foo " + url + "/profiles/changelog?language=foo&name=Basic", + "\"Basic\" - Foo " + url + "/profiles/changelog?language=foo&name=Basic&since=", "&to=", " 1 new rules", " 3 rules have been updated", " 1 rules removed",