mirror of
https://github.com/SonarSource/sonarqube.git
synced 2024-07-28 08:17:45 +02:00
SONAR-2746 Email new alerts on favorite projects
This commit is contained in:
parent
aac947247b
commit
30d668f520
@ -19,10 +19,18 @@
|
||||
*/
|
||||
package org.sonar.plugins.core.sensors;
|
||||
|
||||
import org.sonar.api.batch.*;
|
||||
import org.sonar.api.batch.Decorator;
|
||||
import org.sonar.api.batch.DecoratorContext;
|
||||
import org.sonar.api.batch.DependsUpon;
|
||||
import org.sonar.api.batch.Event;
|
||||
import org.sonar.api.batch.TimeMachine;
|
||||
import org.sonar.api.batch.TimeMachineQuery;
|
||||
import org.sonar.api.measures.CoreMetrics;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.measures.Metric.Level;
|
||||
import org.sonar.api.notifications.Notification;
|
||||
import org.sonar.api.notifications.NotificationManager;
|
||||
import org.sonar.api.profiles.RulesProfile;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.resources.Resource;
|
||||
@ -34,17 +42,18 @@ public class GenerateAlertEvents implements Decorator {
|
||||
|
||||
private final RulesProfile profile;
|
||||
private final TimeMachine timeMachine;
|
||||
private NotificationManager notificationManager;
|
||||
|
||||
public GenerateAlertEvents(RulesProfile profile, TimeMachine timeMachine) {
|
||||
public GenerateAlertEvents(RulesProfile profile, TimeMachine timeMachine, NotificationManager notificationManager) {
|
||||
this.profile = profile;
|
||||
this.timeMachine = timeMachine;
|
||||
this.notificationManager = notificationManager;
|
||||
}
|
||||
|
||||
public boolean shouldExecuteOnProject(Project project) {
|
||||
return profile != null && profile.getAlerts() != null && profile.getAlerts().size() > 0;
|
||||
}
|
||||
|
||||
|
||||
@DependsUpon
|
||||
public Metric dependsUponAlertStatus() {
|
||||
return CoreMetrics.ALERT_STATUS;
|
||||
@ -63,15 +72,41 @@ public class GenerateAlertEvents implements Decorator {
|
||||
List<Measure> measures = timeMachine.getMeasures(query);
|
||||
|
||||
Measure pastStatus = (measures != null && measures.size() == 1 ? measures.get(0) : null);
|
||||
if (pastStatus != null && pastStatus.getDataAsLevel() != currentStatus.getDataAsLevel()) {
|
||||
createEvent(context, getName(pastStatus, currentStatus), currentStatus.getAlertText());
|
||||
String alertText = currentStatus.getAlertText();
|
||||
Level alertLevel = currentStatus.getDataAsLevel();
|
||||
String alertName = null;
|
||||
boolean isNewAlert = true;
|
||||
if (pastStatus != null && pastStatus.getDataAsLevel() != alertLevel) {
|
||||
// The alert status has changed
|
||||
alertName = getName(pastStatus, currentStatus);
|
||||
if (pastStatus.getDataAsLevel() != Metric.Level.OK) {
|
||||
// There was already a Orange/Red alert, so this is no new alert: it has just changed
|
||||
isNewAlert = false;
|
||||
}
|
||||
createEvent(context, alertName, alertText);
|
||||
notifyUsers(resource, alertName, alertText, alertLevel, isNewAlert);
|
||||
|
||||
} else if (pastStatus == null && currentStatus.getDataAsLevel() != Metric.Level.OK) {
|
||||
createEvent(context, getName(currentStatus), currentStatus.getAlertText());
|
||||
} else if (pastStatus == null && alertLevel != Metric.Level.OK) {
|
||||
// There were no defined alerts before, so this one is a new one
|
||||
alertName = getName(currentStatus);
|
||||
createEvent(context, alertName, alertText);
|
||||
notifyUsers(resource, alertName, alertText, alertLevel, isNewAlert);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void notifyUsers(Resource<?> resource, String alertName, String alertText, Level alertLevel, boolean isNewAlert) {
|
||||
Notification notification = new Notification("alerts")
|
||||
.setFieldValue("projectName", resource.getLongName())
|
||||
.setFieldValue("projectKey", resource.getKey())
|
||||
.setFieldValue("projectId", String.valueOf(resource.getId()))
|
||||
.setFieldValue("alertName", alertName)
|
||||
.setFieldValue("alertText", alertText)
|
||||
.setFieldValue("alertLevel", alertLevel.toString())
|
||||
.setFieldValue("isNewAlert", Boolean.toString(isNewAlert));
|
||||
notificationManager.scheduleForSending(notification);
|
||||
}
|
||||
|
||||
private boolean shouldDecorateResource(Resource resource) {
|
||||
return ResourceUtils.isRootProject(resource);
|
||||
}
|
||||
|
@ -1495,6 +1495,7 @@ server_id_configuration.generation_error=Organisation and/or IP address are not
|
||||
notification.channel.EmailNotificationChannel=Email
|
||||
notification.dispatcher.ChangesInReviewAssignedToMeOrCreatedByMe=Changes in review assigned to me or created by me
|
||||
notification.dispatcher.NewViolationsOnMyFavouriteProject=New violations on my favourite projects introduced during the first differential view period
|
||||
notification.dispatcher.AlertsOnMyFavouriteProject=Alerts on my favourite projects
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
@ -28,21 +28,27 @@ import org.sonar.api.batch.TimeMachineQuery;
|
||||
import org.sonar.api.measures.CoreMetrics;
|
||||
import org.sonar.api.measures.Measure;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.notifications.Notification;
|
||||
import org.sonar.api.notifications.NotificationManager;
|
||||
import org.sonar.api.profiles.Alert;
|
||||
import org.sonar.api.profiles.RulesProfile;
|
||||
import org.sonar.api.resources.File;
|
||||
import org.sonar.api.resources.Project;
|
||||
import org.sonar.api.test.ProjectTestBuilder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ -51,6 +57,7 @@ public class GenerateAlertEventsTest {
|
||||
private DecoratorContext context;
|
||||
private RulesProfile profile;
|
||||
private TimeMachine timeMachine;
|
||||
private NotificationManager notificationManager;
|
||||
private Project project;
|
||||
|
||||
@Before
|
||||
@ -58,12 +65,18 @@ public class GenerateAlertEventsTest {
|
||||
context = mock(DecoratorContext.class);
|
||||
timeMachine = mock(TimeMachine.class);
|
||||
profile = mock(RulesProfile.class);
|
||||
decorator = new GenerateAlertEvents(profile, timeMachine);
|
||||
notificationManager = mock(NotificationManager.class);
|
||||
decorator = new GenerateAlertEvents(profile, timeMachine, notificationManager);
|
||||
project = new ProjectTestBuilder().build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doNotDecorateIfNoThresholds() {
|
||||
public void shouldDependUponAlertStatus() {
|
||||
assertThat(decorator.dependsUponAlertStatus()).isEqualTo(CoreMetrics.ALERT_STATUS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotDecorateIfNoThresholds() {
|
||||
assertThat(decorator.shouldExecuteOnProject(project), is(false));
|
||||
}
|
||||
|
||||
@ -73,18 +86,30 @@ public class GenerateAlertEventsTest {
|
||||
assertThat(decorator.shouldExecuteOnProject(project), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotDecorateIfNotRootProject() {
|
||||
decorator.decorate(new File("Foo"), context);
|
||||
verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateEventWhenNewErrorAlert() {
|
||||
when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.ERROR, "desc"));
|
||||
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context).createEvent(Metric.Level.ERROR.getColorName(), "desc", Event.CATEGORY_ALERT, null);
|
||||
verifyNotificationSent("Red", "desc", "ERROR", "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateEventWhenNewWarnAlert() {
|
||||
when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.WARN, "desc"));
|
||||
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context).createEvent(Metric.Level.WARN.getColorName(), "desc", Event.CATEGORY_ALERT, null);
|
||||
verifyNotificationSent("Orange", "desc", "WARN", "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -95,6 +120,7 @@ public class GenerateAlertEventsTest {
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context).createEvent("Red (was Orange)", "desc", Event.CATEGORY_ALERT, null);
|
||||
verifyNotificationSent("Red (was Orange)", "desc", "ERROR", "false");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -105,6 +131,18 @@ public class GenerateAlertEventsTest {
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context).createEvent("Green (was Red)", null, Event.CATEGORY_ALERT, null);
|
||||
verifyNotificationSent("Green (was Red)", null, "OK", "false");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateEventWhenOkToError() {
|
||||
when(timeMachine.getMeasures(any(TimeMachineQuery.class))).thenReturn(Arrays.asList(newAlertStatus(Metric.Level.OK, null)));
|
||||
when(context.getMeasure(CoreMetrics.ALERT_STATUS)).thenReturn(newAlertStatus(Metric.Level.ERROR, "desc"));
|
||||
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context).createEvent("Red (was Green)", "desc", Event.CATEGORY_ALERT, null);
|
||||
verifyNotificationSent("Red (was Green)", "desc", "ERROR", "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -115,6 +153,7 @@ public class GenerateAlertEventsTest {
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context).createEvent("Orange (was Red)", "desc", Event.CATEGORY_ALERT, null);
|
||||
verifyNotificationSent("Orange (was Red)", "desc", "WARN", "false");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -122,6 +161,7 @@ public class GenerateAlertEventsTest {
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
|
||||
verify(notificationManager, never()).scheduleForSending(any(Notification.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -132,6 +172,7 @@ public class GenerateAlertEventsTest {
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
|
||||
verify(notificationManager, never()).scheduleForSending(any(Notification.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -142,6 +183,7 @@ public class GenerateAlertEventsTest {
|
||||
decorator.decorate(project, context);
|
||||
|
||||
verify(context, never()).createEvent(anyString(), anyString(), anyString(), (Date) isNull());
|
||||
verify(notificationManager, never()).scheduleForSending(any(Notification.class));
|
||||
}
|
||||
|
||||
private Measure newAlertStatus(Metric.Level level, String label) {
|
||||
@ -150,4 +192,16 @@ public class GenerateAlertEventsTest {
|
||||
measure.setAlertText(label);
|
||||
return measure;
|
||||
}
|
||||
|
||||
private void verifyNotificationSent(String alertName, String alertText, String alertLevel, String isNewAlert) {
|
||||
Notification notification = new Notification("alerts")
|
||||
.setFieldValue("projectName", project.getLongName())
|
||||
.setFieldValue("projectKey", project.getKey())
|
||||
.setFieldValue("projectId", String.valueOf(project.getId()))
|
||||
.setFieldValue("alertName", alertName)
|
||||
.setFieldValue("alertText", alertText)
|
||||
.setFieldValue("alertLevel", alertLevel)
|
||||
.setFieldValue("isNewAlert", isNewAlert);
|
||||
verify(notificationManager, times(1)).scheduleForSending(eq(notification));
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ package org.sonar.plugins.emailnotifications;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.sonar.api.ServerExtension;
|
||||
import org.sonar.api.SonarPlugin;
|
||||
import org.sonar.plugins.emailnotifications.alerts.AlertsEmailTemplate;
|
||||
import org.sonar.plugins.emailnotifications.alerts.AlertsOnMyFavouriteProject;
|
||||
import org.sonar.plugins.emailnotifications.newviolations.NewViolationsEmailTemplate;
|
||||
import org.sonar.plugins.emailnotifications.newviolations.NewViolationsOnMyFavouriteProject;
|
||||
import org.sonar.plugins.emailnotifications.reviews.ChangesInReviewAssignedToMeOrCreatedByMe;
|
||||
@ -32,10 +34,16 @@ import java.util.List;
|
||||
public class EmailNotificationsPlugin extends SonarPlugin {
|
||||
public List<Class<? extends ServerExtension>> getExtensions() {
|
||||
return ImmutableList.of(
|
||||
ChangesInReviewAssignedToMeOrCreatedByMe.class,
|
||||
EmailNotificationChannel.class,
|
||||
NewViolationsEmailTemplate.class,
|
||||
// Notify incoming violations on my favourite projects
|
||||
NewViolationsOnMyFavouriteProject.class,
|
||||
ReviewEmailTemplate.class);
|
||||
NewViolationsEmailTemplate.class,
|
||||
// Notify reviews changes
|
||||
ChangesInReviewAssignedToMeOrCreatedByMe.class,
|
||||
ReviewEmailTemplate.class,
|
||||
// Notify alerts on my favourite projects
|
||||
AlertsOnMyFavouriteProject.class,
|
||||
AlertsEmailTemplate.class
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2012 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.plugins.emailnotifications.alerts;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.sonar.api.config.EmailSettings;
|
||||
import org.sonar.api.measures.Metric;
|
||||
import org.sonar.api.notifications.Notification;
|
||||
import org.sonar.plugins.emailnotifications.api.EmailMessage;
|
||||
import org.sonar.plugins.emailnotifications.api.EmailTemplate;
|
||||
|
||||
/**
|
||||
* Creates email message for notification "alerts".
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public class AlertsEmailTemplate extends EmailTemplate {
|
||||
|
||||
private EmailSettings configuration;
|
||||
|
||||
public AlertsEmailTemplate(EmailSettings configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmailMessage format(Notification notification) {
|
||||
if (!"alerts".equals(notification.getType())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Retrieve useful values
|
||||
String projectId = notification.getFieldValue("projectId");
|
||||
String projectKey = notification.getFieldValue("projectKey");
|
||||
String projectName = notification.getFieldValue("projectName");
|
||||
String alertName = notification.getFieldValue("alertName");
|
||||
String alertText = notification.getFieldValue("alertText");
|
||||
String alertLevel = notification.getFieldValue("alertLevel");
|
||||
boolean isNewAlert = Boolean.valueOf(notification.getFieldValue("isNewAlert"));
|
||||
|
||||
// Generate text
|
||||
String subject = generateSubject(projectName, alertLevel, isNewAlert);
|
||||
String messageBody = generateMessageBody(projectName, projectKey, alertName, alertText, isNewAlert);
|
||||
|
||||
// And finally return the email that will be sent
|
||||
return new EmailMessage()
|
||||
.setMessageId("alerts/" + projectId)
|
||||
.setSubject(subject)
|
||||
.setMessage(messageBody);
|
||||
}
|
||||
|
||||
private String generateSubject(String projectName, String alertLevel, boolean isNewAlert) {
|
||||
StringBuilder subjectBuilder = new StringBuilder();
|
||||
if (Metric.Level.OK.toString().equals(alertLevel)) {
|
||||
subjectBuilder.append("\"").append(projectName).append("\" is back to green");
|
||||
} else if (isNewAlert) {
|
||||
subjectBuilder.append("New alert on \"").append(projectName).append("\"");
|
||||
} else {
|
||||
subjectBuilder.append("Alert level changed on \"").append(projectName).append("\"");
|
||||
}
|
||||
return subjectBuilder.toString();
|
||||
}
|
||||
|
||||
private String generateMessageBody(String projectName, String projectKey, String alertName, String alertText, boolean isNewAlert) {
|
||||
StringBuilder messageBody = new StringBuilder();
|
||||
messageBody.append("Project: ").append(projectName).append("\n");
|
||||
messageBody.append("Alert level: ").append(alertName).append("\n\n");
|
||||
|
||||
String[] alerts = StringUtils.split(alertText, ",");
|
||||
if (alerts.length > 0) {
|
||||
if (isNewAlert) {
|
||||
messageBody.append("New alert");
|
||||
} else {
|
||||
messageBody.append("Alert");
|
||||
}
|
||||
if (alerts.length == 1) {
|
||||
messageBody.append(": ").append(alerts[0].trim()).append("\n");
|
||||
} else {
|
||||
messageBody.append("s:\n");
|
||||
for (String alert : alerts) {
|
||||
messageBody.append(" - ").append(alert.trim()).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
messageBody.append("\n").append("See it in Sonar: ").append(configuration.getServerBaseURL()).append("/dashboard/index/").append(projectKey);
|
||||
|
||||
return messageBody.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2012 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.plugins.emailnotifications.alerts;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.sonar.api.notifications.Notification;
|
||||
import org.sonar.api.notifications.NotificationDispatcher;
|
||||
import org.sonar.core.properties.PropertiesDao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This dispatcher means: "notify me when alerts are raised on projects that I flagged as favourite".
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public class AlertsOnMyFavouriteProject extends NotificationDispatcher {
|
||||
|
||||
private PropertiesDao propertiesDao;
|
||||
|
||||
public AlertsOnMyFavouriteProject(PropertiesDao propertiesDao) {
|
||||
this.propertiesDao = propertiesDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(Notification notification, Context context) {
|
||||
if (StringUtils.equals(notification.getType(), "alerts")) {
|
||||
Long projectId = Long.parseLong(notification.getFieldValue("projectId"));
|
||||
List<String> userLogins = propertiesDao.findUserIdsForFavouriteResource(projectId);
|
||||
for (String userLogin : userLogins) {
|
||||
context.addUser(userLogin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2012 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.plugins.emailnotifications.alerts;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.config.EmailSettings;
|
||||
import org.sonar.api.notifications.Notification;
|
||||
import org.sonar.plugins.emailnotifications.api.EmailMessage;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class AlertsEmailTemplateTest {
|
||||
|
||||
private AlertsEmailTemplate template;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
EmailSettings configuration = mock(EmailSettings.class);
|
||||
when(configuration.getServerBaseURL()).thenReturn("http://nemo.sonarsource.org");
|
||||
template = new AlertsEmailTemplate(configuration);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotFormatIfNotCorrectNotification() {
|
||||
Notification notification = new Notification("other-notif");
|
||||
EmailMessage message = template.format(notification);
|
||||
assertThat(message, nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFormatAlertWithSeveralMessages() {
|
||||
Notification notification = createNotification("Orange (was Red)", "violations > 4, coverage < 75%", "WARN", "false");
|
||||
|
||||
EmailMessage message = template.format(notification);
|
||||
assertThat(message.getMessageId(), is("alerts/45"));
|
||||
assertThat(message.getSubject(), is("Alert level changed on \"Foo\""));
|
||||
assertThat(message.getMessage(), is("" +
|
||||
"Project: Foo\n" +
|
||||
"Alert level: Orange (was Red)\n" +
|
||||
"\n" +
|
||||
"Alerts:\n" +
|
||||
" - violations > 4\n" +
|
||||
" - coverage < 75%\n" +
|
||||
"\n" +
|
||||
"See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFormatNewAlertWithSeveralMessages() {
|
||||
Notification notification = createNotification("Orange (was Red)", "violations > 4, coverage < 75%", "WARN", "true");
|
||||
|
||||
EmailMessage message = template.format(notification);
|
||||
assertThat(message.getMessageId(), is("alerts/45"));
|
||||
assertThat(message.getSubject(), is("New alert on \"Foo\""));
|
||||
assertThat(message.getMessage(), is("" +
|
||||
"Project: Foo\n" +
|
||||
"Alert level: Orange (was Red)\n" +
|
||||
"\n" +
|
||||
"New alerts:\n" +
|
||||
" - violations > 4\n" +
|
||||
" - coverage < 75%\n" +
|
||||
"\n" +
|
||||
"See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFormatNewAlertWithOneMessage() {
|
||||
Notification notification = createNotification("Orange (was Red)", "violations > 4", "WARN", "true");
|
||||
|
||||
EmailMessage message = template.format(notification);
|
||||
assertThat(message.getMessageId(), is("alerts/45"));
|
||||
assertThat(message.getSubject(), is("New alert on \"Foo\""));
|
||||
assertThat(message.getMessage(), is("" +
|
||||
"Project: Foo\n" +
|
||||
"Alert level: Orange (was Red)\n" +
|
||||
"\n" +
|
||||
"New alert: violations > 4\n" +
|
||||
"\n" +
|
||||
"See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFormatBackToGreenMessage() {
|
||||
Notification notification = createNotification("Green (was Red)", "", "OK", "false");
|
||||
|
||||
EmailMessage message = template.format(notification);
|
||||
assertThat(message.getMessageId(), is("alerts/45"));
|
||||
assertThat(message.getSubject(), is("\"Foo\" is back to green"));
|
||||
assertThat(message.getMessage(), is("" +
|
||||
"Project: Foo\n" +
|
||||
"Alert level: Green (was Red)\n" +
|
||||
"\n" +
|
||||
"\n" +
|
||||
"See it in Sonar: http://nemo.sonarsource.org/dashboard/index/org.sonar.foo:foo"));
|
||||
}
|
||||
|
||||
private Notification createNotification(String alertName, String alertText, String alertLevel, String isNewAlert) {
|
||||
Notification notification = new Notification("alerts")
|
||||
.setFieldValue("projectName", "Foo")
|
||||
.setFieldValue("projectKey", "org.sonar.foo:foo")
|
||||
.setFieldValue("projectId", "45")
|
||||
.setFieldValue("alertName", alertName)
|
||||
.setFieldValue("alertText", alertText)
|
||||
.setFieldValue("alertLevel", alertLevel)
|
||||
.setFieldValue("isNewAlert", isNewAlert);
|
||||
return notification;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Sonar, open source software quality management tool.
|
||||
* Copyright (C) 2008-2012 SonarSource
|
||||
* mailto:contact AT sonarsource DOT com
|
||||
*
|
||||
* Sonar 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.
|
||||
*
|
||||
* Sonar 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 Sonar; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
|
||||
*/
|
||||
package org.sonar.plugins.emailnotifications.alerts;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.Test;
|
||||
import org.sonar.api.notifications.Notification;
|
||||
import org.sonar.api.notifications.NotificationDispatcher;
|
||||
import org.sonar.core.properties.PropertiesDao;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class AlertsOnMyFavouriteProjectTest {
|
||||
|
||||
@Test
|
||||
public void shouldNotDispatchIfNotNewViolationsNotification() throws Exception {
|
||||
NotificationDispatcher.Context context = mock(NotificationDispatcher.Context.class);
|
||||
AlertsOnMyFavouriteProject dispatcher = new AlertsOnMyFavouriteProject(null);
|
||||
Notification notification = new Notification("other-notif");
|
||||
dispatcher.dispatch(notification, context);
|
||||
|
||||
verify(context, never()).addUser(any(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDispatchToUsersWhoHaveFlaggedProjectAsFavourite() {
|
||||
NotificationDispatcher.Context context = mock(NotificationDispatcher.Context.class);
|
||||
PropertiesDao propertiesDao = mock(PropertiesDao.class);
|
||||
when(propertiesDao.findUserIdsForFavouriteResource(34L)).thenReturn(Lists.newArrayList("user1", "user2"));
|
||||
AlertsOnMyFavouriteProject dispatcher = new AlertsOnMyFavouriteProject(propertiesDao);
|
||||
|
||||
Notification notification = new Notification("alerts").setFieldValue("projectId", "34");
|
||||
dispatcher.dispatch(notification, context);
|
||||
|
||||
verify(context).addUser("user1");
|
||||
verify(context).addUser("user2");
|
||||
verifyNoMoreInteractions(context);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user