aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Mandrikov <mandrikov@gmail.com>2011-07-27 18:16:16 +0400
committerEvgeny Mandrikov <mandrikov@gmail.com>2011-07-27 20:59:45 +0400
commita24cd25f9ca3062d601164c2d0c38c0c1aa919b4 (patch)
tree01fc0540b5b8cd142dfc736978005f460be961e2
parent79e08b37ee316ccd238e272aabb5313cee60bc00 (diff)
downloadsonarqube-a24cd25f9ca3062d601164c2d0c38c0c1aa919b4.tar.gz
sonarqube-a24cd25f9ca3062d601164c2d0c38c0c1aa919b4.zip
SONAR-2607 Show in notification: project, resource and title of review
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CloseReviewsDecorator.java42
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CloseReviewsDecoratorTest.java10
-rw-r--r--plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplate.java11
-rw-r--r--plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplateTest.java137
-rw-r--r--sonar-server/src/main/java/org/sonar/server/notifications/reviews/ReviewsNotificationManager.java3
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/review.rb5
6 files changed, 180 insertions, 28 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CloseReviewsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CloseReviewsDecorator.java
index 6e17f67f66d..529c42dd29a 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CloseReviewsDecorator.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CloseReviewsDecorator.java
@@ -49,12 +49,14 @@ public class CloseReviewsDecorator implements Decorator {
private static final Logger LOG = LoggerFactory.getLogger(CloseReviewsDecorator.class);
+ private Project project;
private ResourcePersister resourcePersister;
private DatabaseSession databaseSession;
private NotificationManager notificationManager;
private UserFinder userFinder;
- public CloseReviewsDecorator(ResourcePersister resourcePersister, DatabaseSession databaseSession, NotificationManager notificationManager, UserFinder userFinder) {
+ public CloseReviewsDecorator(Project project, ResourcePersister resourcePersister, DatabaseSession databaseSession, NotificationManager notificationManager, UserFinder userFinder) {
+ this.project = project;
this.resourcePersister = resourcePersister;
this.databaseSession = databaseSession;
this.notificationManager = notificationManager;
@@ -71,8 +73,8 @@ public class CloseReviewsDecorator implements Decorator {
int resourceId = currentSnapshot.getResourceId();
int snapshotId = currentSnapshot.getId();
- closeReviews(resourceId, snapshotId);
- reopenReviews(resourceId);
+ closeReviews(resource, resourceId, snapshotId);
+ reopenReviews(resource, resourceId);
if (ResourceUtils.isRootProject(resource)) {
closeReviewsForDeletedResources(resourceId, currentSnapshot.getId());
}
@@ -84,13 +86,13 @@ public class CloseReviewsDecorator implements Decorator {
/**
* Close reviews for which violations have been fixed.
*/
- protected int closeReviews(int resourceId, int snapshotId) {
+ protected int closeReviews(Resource resource, int resourceId, int snapshotId) {
String conditions = " WHERE status!='CLOSED' AND resource_id=" + resourceId
+ " AND rule_failure_permanent_id NOT IN " + "(SELECT permanent_id FROM rule_failures WHERE snapshot_id=" + snapshotId
+ " AND permanent_id IS NOT NULL)";
List<Review> reviews = databaseSession.getEntityManager().createNativeQuery("SELECT * FROM reviews " + conditions, Review.class).getResultList();
for (Review review : reviews) {
- notifyClosed(review);
+ notifyClosed(resource, review);
}
int rowUpdated = databaseSession.createNativeQuery("UPDATE reviews SET status='CLOSED', updated_at=CURRENT_TIMESTAMP" + conditions).executeUpdate();
LOG.debug("- {} reviews set to 'closed' on resource #{}", rowUpdated, resourceId);
@@ -100,11 +102,11 @@ public class CloseReviewsDecorator implements Decorator {
/**
* Reopen reviews that had been set to resolved but for which the violation is still here.
*/
- protected int reopenReviews(int resourceId) {
+ protected int reopenReviews(Resource resource, int resourceId) {
String conditions = " WHERE status='RESOLVED' AND resource_id=" + resourceId;
List<Review> reviews = databaseSession.getEntityManager().createNativeQuery("SELECT * FROM reviews " + conditions, Review.class).getResultList();
for (Review review : reviews) {
- notifyReopened(review);
+ notifyReopened(resource, review);
}
int rowUpdated = databaseSession.createNativeQuery("UPDATE reviews SET status='REOPENED', resolution=NULL, updated_at=CURRENT_TIMESTAMP" + conditions).executeUpdate();
LOG.debug("- {} reviews set to 'reopened' on resource #{}", rowUpdated, resourceId);
@@ -123,7 +125,7 @@ public class CloseReviewsDecorator implements Decorator {
.setParameter(1, Boolean.TRUE)
.getResultList();
for (Review review : reviews) {
- notifyClosed(review);
+ notifyClosed(null, review);
}
int rowUpdated = databaseSession.createNativeQuery("UPDATE reviews SET status='CLOSED', updated_at=CURRENT_TIMESTAMP" + conditions)
.setParameter(1, Boolean.TRUE)
@@ -148,11 +150,8 @@ public class CloseReviewsDecorator implements Decorator {
return user != null ? user.getLogin() : null;
}
- void notifyReopened(Review review) {
- Notification notification = new Notification("review-changed")
- .setFieldValue("reviewId", String.valueOf(review.getId()))
- .setFieldValue("creator", getCreator(review))
- .setFieldValue("assignee", getAssignee(review))
+ void notifyReopened(Resource resource, Review review) {
+ Notification notification = createReviewNotification(resource, review)
.setFieldValue("old.status", review.getStatus())
.setFieldValue("new.status", "REOPENED")
.setFieldValue("old.resolution", review.getResolution())
@@ -160,14 +159,21 @@ public class CloseReviewsDecorator implements Decorator {
notificationManager.scheduleForSending(notification);
}
- void notifyClosed(Review review) {
- Notification notification = new Notification("review-changed")
- .setFieldValue("reviewId", String.valueOf(review.getId()))
- .setFieldValue("creator", getCreator(review))
- .setFieldValue("assignee", getAssignee(review))
+ void notifyClosed(Resource resource, Review review) {
+ Notification notification = createReviewNotification(resource, review)
.setFieldValue("old.status", review.getStatus())
.setFieldValue("new.status", "CLOSED");
notificationManager.scheduleForSending(notification);
}
+ private Notification createReviewNotification(Resource resource, Review review) {
+ return new Notification("review-changed")
+ .setFieldValue("reviewId", String.valueOf(review.getId()))
+ .setFieldValue("project", project.getRoot().getLongName())
+ .setFieldValue("resource", resource != null ? resource.getLongName() : null)
+ .setFieldValue("title", review.getTitle())
+ .setFieldValue("creator", getCreator(review))
+ .setFieldValue("assignee", getAssignee(review));
+ }
+
}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CloseReviewsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CloseReviewsDecoratorTest.java
index 19c04f675c8..afab33e4d78 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CloseReviewsDecoratorTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CloseReviewsDecoratorTest.java
@@ -45,8 +45,10 @@ public class CloseReviewsDecoratorTest extends AbstractDbUnitTestCase {
@Before
public void setUp() {
+ Project project = mock(Project.class);
+ when(project.getRoot()).thenReturn(project);
notificationManager = mock(NotificationManager.class);
- reviewsDecorator = new CloseReviewsDecorator(null, getSession(), notificationManager, mock(UserFinder.class));
+ reviewsDecorator = new CloseReviewsDecorator(project, null, getSession(), notificationManager, mock(UserFinder.class));
}
@Test
@@ -60,7 +62,7 @@ public class CloseReviewsDecoratorTest extends AbstractDbUnitTestCase {
public void shouldCloseReviewWithoutCorrespondingViolation() throws Exception {
setupData("fixture");
- int count = reviewsDecorator.closeReviews(666, 222);
+ int count = reviewsDecorator.closeReviews(null, 666, 222);
assertThat(count, is(3));
verify(notificationManager, times(3)).scheduleForSending(any(Notification.class));
@@ -79,10 +81,10 @@ public class CloseReviewsDecoratorTest extends AbstractDbUnitTestCase {
setupData("fixture");
// First we close the reviews for which the violations have been fixed (this is because we use the same "fixture"...)
- reviewsDecorator.closeReviews(666, 222);
+ reviewsDecorator.closeReviews(null, 666, 222);
// And now we reopen the reviews that still have a violation
- int count = reviewsDecorator.reopenReviews(666);
+ int count = reviewsDecorator.reopenReviews(null, 666);
assertThat(count, is(1));
verify(notificationManager, times(4)).scheduleForSending(any(Notification.class));
diff --git a/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplate.java b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplate.java
index 00c68c11dd8..1373ed8059b 100644
--- a/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplate.java
+++ b/plugins/sonar-email-notifications-plugin/src/main/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplate.java
@@ -44,13 +44,18 @@ public class ReviewEmailTemplate extends EmailTemplate {
@Override
public EmailMessage format(Notification notification) {
- if ( !"review-changed".equals(notification.getType())) {
+ if (!"review-changed".equals(notification.getType())) {
return null;
}
String reviewId = notification.getFieldValue("reviewId");
String author = notification.getFieldValue("author");
StringBuilder sb = new StringBuilder();
+ append(sb, "Project", null, notification.getFieldValue("project"));
+ append(sb, "Resource", null, notification.getFieldValue("resource"));
+ sb.append('\n');
+ append(sb, null, null, notification.getFieldValue("title"));
+ sb.append('\n');
append(sb, "Status", notification.getFieldValue("old.status"), notification.getFieldValue("new.status"));
append(sb, "Resolution", notification.getFieldValue("old.resolution"), notification.getFieldValue("new.resolution"));
append(sb, "Assignee", getUserFullName(notification.getFieldValue("old.assignee")), getUserFullName(notification.getFieldValue("new.assignee")));
@@ -69,7 +74,9 @@ public class ReviewEmailTemplate extends EmailTemplate {
private void append(StringBuilder sb, String name, String oldValue, String newValue) {
if (oldValue != null || newValue != null) {
- sb.append(name).append(": ");
+ if (name != null) {
+ sb.append(name).append(": ");
+ }
if (newValue != null) {
sb.append(newValue);
}
diff --git a/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplateTest.java b/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplateTest.java
index b217f3d2585..fc8e24756b7 100644
--- a/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplateTest.java
+++ b/plugins/sonar-email-notifications-plugin/src/test/java/org/sonar/plugins/emailnotifications/reviews/ReviewEmailTemplateTest.java
@@ -54,6 +54,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Freddy Mallet
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Comment:
* This is my first comment
*
@@ -65,6 +70,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatCommentAdded() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("author", "freddy.mallet")
.setFieldValue("old.comment", null)
.setFieldValue("new.comment", "This is my first comment");
@@ -73,6 +81,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Freddy Mallet"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Comment:\n" +
" This is my first comment\n" +
"\n" +
@@ -85,6 +98,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Freddy Mallet
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Comment:
* This is another comment
* Was:
@@ -98,6 +116,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatCommentEdited() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("author", "freddy.mallet")
.setFieldValue("old.comment", "This is my first comment")
.setFieldValue("new.comment", "This is another comment");
@@ -106,6 +127,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Freddy Mallet"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Comment:\n" +
" This is another comment\n" +
"Was:\n" +
@@ -120,6 +146,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Freddy Mallet
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Comment deleted, was:
* This is deleted comment
*
@@ -131,6 +162,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatCommentDeleted() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("old.comment", "This is deleted comment")
.setFieldValue("new.comment", null)
.setFieldValue("author", "freddy.mallet");
@@ -139,6 +173,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Freddy Mallet"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Comment deleted, was:\n" +
" This is deleted comment\n" +
"\n" +
@@ -151,6 +190,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Freddy Mallet
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Assignee: Evgeny Mandrikov
*
* --
@@ -161,6 +205,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatAssigneed() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("author", "freddy.mallet")
.setFieldValue("old.assignee", null)
.setFieldValue("new.assignee", "evgeny.mandrikov");
@@ -169,6 +216,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Freddy Mallet"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Assignee: Evgeny Mandrikov\n" +
"\n" +
"--\n" +
@@ -180,6 +232,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Freddy Mallet
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Assignee: Simon Brandhof (was Evgeny Mandrikov)
*
* --
@@ -190,6 +247,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatAssigneedToAnotherPerson() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("author", "freddy.mallet")
.setFieldValue("old.assignee", "evgeny.mandrikov")
.setFieldValue("new.assignee", "simon.brandhof");
@@ -198,6 +258,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Freddy Mallet"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Assignee: Simon Brandhof (was Evgeny Mandrikov)\n" +
"\n" +
"--\n" +
@@ -209,6 +274,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Freddy Mallet
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Assignee: (was Simon Brandhof)
*
* --
@@ -219,6 +289,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatUnassigned() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("author", "freddy.mallet")
.setFieldValue("old.assignee", "simon.brandhof")
.setFieldValue("new.assignee", null);
@@ -227,6 +300,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Freddy Mallet"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Assignee: (was Simon Brandhof)\n" +
"\n" +
"--\n" +
@@ -238,6 +316,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Sonar
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Status: CLOSED (was OPEN)
*
* --
@@ -248,6 +331,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatClosed() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("old.status", "OPEN")
.setFieldValue("new.status", "CLOSED");
EmailMessage message = template.format(notification);
@@ -255,10 +341,15 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), nullValue());
assertThat(message.getMessage(), is("" +
- "Status: CLOSED (was OPEN)\n" +
- "\n" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
+ "Status: CLOSED (was OPEN)\n" +
+ "\n" +
"--\n" +
- "See it in Sonar: http://nemo.sonarsource.org/reviews/view/1\n"));
+ "See it in Sonar: http://nemo.sonarsource.org/reviews/view/1\n"));
}
/**
@@ -266,6 +357,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Simon Brandhof
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Status: REOPENED (was RESOLVED)
* Resolution: (was FIXED)
*
@@ -277,6 +373,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatReopened() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("old.resolution", "FIXED")
.setFieldValue("new.resolution", null)
.setFieldValue("old.status", "RESOLVED")
@@ -286,6 +385,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), nullValue());
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Status: REOPENED (was RESOLVED)\n" +
"Resolution: (was FIXED)\n" +
"\n" +
@@ -298,6 +402,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Simon Brandhof
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Status: RESOLVED (was OPEN)
* Resolution: FIXED
*
@@ -309,6 +418,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatResolvedAsFixed() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("author", "simon.brandhof")
.setFieldValue("old.status", "OPEN")
.setFieldValue("old.resolution", null)
@@ -319,6 +431,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Simon Brandhof"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Status: RESOLVED (was OPEN)\n" +
"Resolution: FIXED\n" +
"\n" +
@@ -331,6 +448,11 @@ public class ReviewEmailTemplateTest {
* Subject: Review #1
* From: Simon Brandhof
*
+ * Project: Sonar
+ * Resource: org.sonar.server.ui.DefaultPages
+ *
+ * Utility classes should not have a public or default constructor.
+ *
* Status: RESOLVED (was REOPENED)
* Resolution: FALSE-POSITIVE
* Comment:
@@ -344,6 +466,9 @@ public class ReviewEmailTemplateTest {
public void shouldFormatResolvedAsFalsePositive() {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", "1")
+ .setFieldValue("project", "Sonar")
+ .setFieldValue("resource", "org.sonar.server.ui.DefaultPages")
+ .setFieldValue("title", "Utility classes should not have a public or default constructor.")
.setFieldValue("author", "freddy.mallet")
.setFieldValue("old.status", "REOPENED")
.setFieldValue("old.resolution", null)
@@ -355,6 +480,11 @@ public class ReviewEmailTemplateTest {
assertThat(message.getSubject(), is("Review #1"));
assertThat(message.getFrom(), is("Freddy Mallet"));
assertThat(message.getMessage(), is("" +
+ "Project: Sonar\n" +
+ "Resource: org.sonar.server.ui.DefaultPages\n" +
+ "\n" +
+ "Utility classes should not have a public or default constructor.\n" +
+ "\n" +
"Status: RESOLVED (was REOPENED)\n" +
"Resolution: FALSE-POSITIVE\n" +
"Comment:\n" +
@@ -375,6 +505,7 @@ public class ReviewEmailTemplateTest {
public void shouldReturnFullNameOrLogin() {
assertThat(template.getUserFullName("freddy.mallet"), is("Freddy Mallet"));
assertThat(template.getUserFullName("deleted"), is("deleted"));
+ assertThat(template.getUserFullName(null), nullValue());
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/notifications/reviews/ReviewsNotificationManager.java b/sonar-server/src/main/java/org/sonar/server/notifications/reviews/ReviewsNotificationManager.java
index eeff3aa75a2..80240c7bee7 100644
--- a/sonar-server/src/main/java/org/sonar/server/notifications/reviews/ReviewsNotificationManager.java
+++ b/sonar-server/src/main/java/org/sonar/server/notifications/reviews/ReviewsNotificationManager.java
@@ -49,6 +49,9 @@ public class ReviewsNotificationManager implements ServerComponent {
public void notifyChanged(Long reviewId, String author, Map<String, String> oldValues, Map<String, String> newValues) {
Notification notification = new Notification("review-changed")
.setFieldValue("reviewId", String.valueOf(reviewId))
+ .setFieldValue("project", newValues.get("project"))
+ .setFieldValue("resource", newValues.get("resource"))
+ .setFieldValue("title", newValues.get("title"))
.setFieldValue("author", author)
.setFieldValue("creator", newValues.get("creator"))
.setFieldValue("assignee", newValues.get("assignee"));
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb
index e376c832739..b639eb90849 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb
@@ -102,7 +102,10 @@ class Review < ActiveRecord::Base
def to_java_map(params = {})
map = java.util.HashMap.new({
- "creator" => user.login.to_java,
+ "project" => project.long_name.to_java,
+ "resource" => resource.long_name.to_java,
+ "title" => title.to_java,
+ "creator" => user == nil ? nil : user.login.to_java,
"assignee" => assignee == nil ? nil : assignee.login.to_java,
"status" => status.to_java,
"resolution" => resolution.to_java