diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-09-19 09:49:38 +0200 |
---|---|---|
committer | Eric Hartmann <hartmann.eric@gmail.Com> | 2017-10-02 13:03:35 +0200 |
commit | df5fdae73ab3269c46e9b4138dc4ea3143425821 (patch) | |
tree | 525c3fcd10a0ba2365e2b8f899084f154065ecf0 | |
parent | 310ed53e7f5abec4fffb4998879769c1d733ac96 (diff) | |
download | sonarqube-df5fdae73ab3269c46e9b4138dc4ea3143425821.tar.gz sonarqube-df5fdae73ab3269c46e9b4138dc4ea3143425821.zip |
SONAR-9552 add version to New Issues notification emails
8 files changed, 118 insertions, 19 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStep.java index ff8bc5ad97b..c145b30d61b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStep.java @@ -137,6 +137,7 @@ public class SendIssueNotificationsStep implements ComputationStep { NewIssuesNotification notification = newIssuesNotificationFactory .newNewIssuesNotication() .setProject(project.getPublicKey(), project.getUuid(), project.getName(), getBranchName()) + .setProjectVersion(project.getReportAttributes().getVersion()) .setAnalysisDate(new Date(analysisDate)) .setStatistics(project.getName(), globalStatistics) .setDebt(Duration.create(globalStatistics.effort().getOnLeak())); @@ -155,6 +156,7 @@ public class SendIssueNotificationsStep implements ComputationStep { .setAssignee(assignee); myNewIssuesNotification .setProject(project.getPublicKey(), project.getUuid(), project.getName(), getBranchName()) + .setProjectVersion(project.getReportAttributes().getVersion()) .setAnalysisDate(new Date(analysisDate)) .setStatistics(project.getName(), assigneeStatistics) .setDebt(Duration.create(assigneeStatistics.effort().getOnLeak())); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java b/server/sonar-server/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java index cf7bfafbe79..ec3ccd8a803 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java @@ -52,6 +52,7 @@ public abstract class AbstractNewIssuesEmailTemplate extends EmailTemplate { static final String FIELD_PROJECT_KEY = "projectKey"; static final String FIELD_PROJECT_DATE = "projectDate"; static final String FIELD_PROJECT_UUID = "projectUuid"; + static final String FIELD_PROJECT_VERSION = "projectVersion"; static final String FIELD_ASSIGNEE = "assignee"; static final String FIELD_BRANCH = "branch"; @@ -81,7 +82,12 @@ public abstract class AbstractNewIssuesEmailTemplate extends EmailTemplate { String fullProjectName = computeFullProjectName(projectName, branchName); StringBuilder message = new StringBuilder(); - message.append("Project: ").append(fullProjectName).append(NEW_LINE).append(NEW_LINE); + message.append("Project: ").append(fullProjectName).append(NEW_LINE); + String version = notification.getFieldValue(FIELD_PROJECT_VERSION); + if (version != null) { + message.append("Version: ").append(version).append(NEW_LINE); + } + message.append(NEW_LINE); appendRuleType(message, notification); appendAssignees(message, notification); appendRules(message, notification); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/notification/NewIssuesNotification.java b/server/sonar-server/src/main/java/org/sonar/server/issue/notification/NewIssuesNotification.java index b2e4d46f6e2..3f5df507eb3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/notification/NewIssuesNotification.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/notification/NewIssuesNotification.java @@ -45,6 +45,7 @@ import org.sonar.server.user.index.UserDoc; import org.sonar.server.user.index.UserIndex; import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_BRANCH; +import static org.sonar.server.issue.notification.AbstractNewIssuesEmailTemplate.FIELD_PROJECT_VERSION; import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.FIELD_PROJECT_DATE; import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.FIELD_PROJECT_KEY; import static org.sonar.server.issue.notification.NewIssuesEmailTemplate.FIELD_PROJECT_NAME; @@ -89,6 +90,13 @@ public class NewIssuesNotification extends Notification { return this; } + public NewIssuesNotification setProjectVersion(@Nullable String version) { + if (version != null) { + setFieldValue(FIELD_PROJECT_VERSION, version); + } + return this; + } + public NewIssuesNotification setStatistics(String projectName, NewIssuesStatistics.Stats stats) { setDefaultMessage(stats.getDistributedMetricStats(RULE_TYPE).getOnLeak() + " new issues on " + projectName + ".\n"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStepTest.java index 016cc0e584e..8646a7bb46c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/SendIssueNotificationsStepTest.java @@ -27,6 +27,7 @@ import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; +import org.apache.commons.lang.RandomStringUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -87,7 +88,9 @@ public class SendIssueNotificationsStepTest extends BaseStepTest { private static final String ISSUE_ASSIGNEE = "John"; private static final Component FILE = builder(Component.Type.FILE, 11).build(); - private static final Component PROJECT = builder(Type.PROJECT, 1).addChildren(FILE).build(); + private static final Component PROJECT = builder(Type.PROJECT, 1) + .setVersion(RandomStringUtils.randomAlphanumeric(10)) + .addChildren(FILE).build(); @Rule public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule() @@ -423,6 +426,7 @@ public class SendIssueNotificationsStepTest extends BaseStepTest { private NewIssuesNotification createNewIssuesNotificationMock() { NewIssuesNotification notification = mock(NewIssuesNotification.class); when(notification.setProject(anyString(), anyString(), anyString(), anyString())).thenReturn(notification); + when(notification.setProjectVersion(anyString())).thenReturn(notification); when(notification.setAnalysisDate(any(Date.class))).thenReturn(notification); when(notification.setStatistics(anyString(), any(NewIssuesStatistics.Stats.class))).thenReturn(notification); when(notification.setDebt(any(Duration.class))).thenReturn(notification); @@ -433,6 +437,7 @@ public class SendIssueNotificationsStepTest extends BaseStepTest { MyNewIssuesNotification notification = mock(MyNewIssuesNotification.class); when(notification.setAssignee(anyString())).thenReturn(notification); when(notification.setProject(anyString(), anyString(), anyString(), anyString())).thenReturn(notification); + when(notification.setProjectVersion(anyString())).thenReturn(notification); when(notification.setAnalysisDate(any(Date.class))).thenReturn(notification); when(notification.setStatistics(anyString(), any(NewIssuesStatistics.Stats.class))).thenReturn(notification); when(notification.setDebt(any(Duration.class))).thenReturn(notification); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java index e5300cd493b..98741da80e7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java @@ -140,13 +140,15 @@ public class MyNewIssuesEmailTemplateTest { @Test public void format_email_with_no_assignees_tags_nor_components() throws Exception { - Notification notification = newNotification(32); + Notification notification = newNotification(32) + .setFieldValue("projectVersion", "52.0"); EmailMessage message = underTest.format(notification); // TODO datetime to be completed when test is isolated from JVM timezone assertThat(message.getMessage()) .startsWith("Project: Struts\n" + + "Version: 52.0\n" + "\n" + "32 new issues (new debt: 1d3h)\n" + "\n" + @@ -159,6 +161,7 @@ public class MyNewIssuesEmailTemplateTest { @Test public void format_email_with_issue_on_branch() throws Exception { Notification notification = newNotification(32) + .setFieldValue("projectVersion", "52.0") .setFieldValue("branch", "feature1"); EmailMessage message = underTest.format(notification); @@ -166,6 +169,7 @@ public class MyNewIssuesEmailTemplateTest { // TODO datetime to be completed when test is isolated from JVM timezone assertThat(message.getMessage()) .startsWith("Project: Struts (feature1)\n" + + "Version: 52.0\n" + "\n" + "32 new issues (new debt: 1d3h)\n" + "\n" + @@ -186,6 +190,25 @@ public class MyNewIssuesEmailTemplateTest { } @Test + public void format_supports_null_version() { + Notification notification = newNotification(32) + .setFieldValue("branch", "feature1"); + + EmailMessage message = underTest.format(notification); + + // TODO datetime to be completed when test is isolated from JVM timezone + assertThat(message.getMessage()) + .startsWith("Project: Struts (feature1)\n" + + "\n" + + "32 new issues (new debt: 1d3h)\n" + + "\n" + + " Type\n" + + " Bug: 1 Vulnerability: 3 Code Smell: 0\n" + + "\n" + + "More details at: http://nemo.sonarsource.org/project/issues?id=org.apache%3Astruts&assignees=lo.gin&branch=feature1&createdAt=2010-05-18"); + } + + @Test public void do_not_add_footer_when_properties_missing() { Notification notification = new Notification(MyNewIssuesNotification.MY_NEW_ISSUES_NOTIF_TYPE) .setFieldValue(RULE_TYPE + ".count", "32") diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java index 03a63654ebf..36d78f01ae0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java @@ -105,7 +105,8 @@ public class NewIssuesEmailTemplateTest { @Test public void format_email_with_all_fields_filled() throws Exception { - Notification notification = newNotification(32); + Notification notification = newNotification(32) + .setFieldValue("projectVersion", "42.1.1"); addAssignees(notification); addRules(notification); addTags(notification); @@ -116,6 +117,7 @@ public class NewIssuesEmailTemplateTest { // TODO datetime to be completed when test is isolated from JVM timezone assertThat(message.getMessage()) .startsWith("Project: Struts\n" + + "Version: 42.1.1\n" + "\n" + "32 new issues (new debt: 1d3h)\n" + "\n" + @@ -142,7 +144,7 @@ public class NewIssuesEmailTemplateTest { } @Test - public void format_email_with_no_assignees_tags_nor_components() throws Exception { + public void format_email_with_no_assignees_tags_nor_components_nor_version() throws Exception { Notification notification = newNotification(32); EmailMessage message = template.format(notification); @@ -189,6 +191,27 @@ public class NewIssuesEmailTemplateTest { } @Test + public void format_email_with_issue_on_branch_with_version() throws Exception { + Notification notification = newNotification(32) + .setFieldValue("branch", "feature1") + .setFieldValue("projectVersion", "42.1.1"); + + EmailMessage message = template.format(notification); + + // TODO datetime to be completed when test is isolated from JVM timezone + assertThat(message.getMessage()) + .startsWith("Project: Struts (feature1)\n" + + "Version: 42.1.1\n" + + "\n" + + "32 new issues (new debt: 1d3h)\n" + + "\n" + + " Type\n" + + " Bug: 1 Vulnerability: 10 Code Smell: 3\n" + + "\n" + + "More details at: http://nemo.sonarsource.org/project/issues?id=org.apache%3Astruts&branch=feature1&createdAt=2010-05-1"); + } + + @Test public void do_not_add_footer_when_properties_missing() { Notification notification = new Notification(NewIssuesNotification.TYPE) .setFieldValue(RULE_TYPE + ".count", "32") diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesNotificationTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesNotificationTest.java index 9ca07bbfae3..edcefd30ed2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesNotificationTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewIssuesNotificationTest.java @@ -102,6 +102,23 @@ public class NewIssuesNotificationTest { } @Test + public void set_project_version() { + String version = randomAlphanumeric(5); + + underTest.setProjectVersion(version); + + assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_VERSION)).isEqualTo(version); + } + + @Test + public void set_project_version_supports_null() { + underTest.setProjectVersion(null); + + assertThat(underTest.getFieldValue(NewIssuesEmailTemplate.FIELD_PROJECT_VERSION)).isNull(); + + } + + @Test public void set_date() { Date date = new Date(); diff --git a/tests/src/test/java/org/sonarqube/tests/issue/IssueNotificationsTest.java b/tests/src/test/java/org/sonarqube/tests/issue/IssueNotificationsTest.java index 7fb89f7cdaf..a8ffdb9c0dd 100644 --- a/tests/src/test/java/org/sonarqube/tests/issue/IssueNotificationsTest.java +++ b/tests/src/test/java/org/sonarqube/tests/issue/IssueNotificationsTest.java @@ -21,6 +21,7 @@ package org.sonarqube.tests.issue; import java.util.Iterator; import javax.mail.internet.MimeMessage; +import org.apache.commons.lang.RandomStringUtils; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -132,12 +133,14 @@ public class IssueNotificationsTest extends AbstractIssueTest { .setParam("type", "SQ-MyNewIssues") .setParam("channel", "EmailNotificationChannel")) .failIfNotSuccessful(); - } @Test public void notifications_for_new_issues_and_issue_changes() throws Exception { - runProjectAnalysis(ORCHESTRATOR, "shared/xoo-sample", "sonar.projectDate", "2015-12-15"); + String version = RandomStringUtils.randomAlphanumeric(10); + runProjectAnalysis(ORCHESTRATOR, "shared/xoo-sample", + "sonar.projectDate", "2015-12-15", + "sonar.projectVersion", version); // change assignee Issues issues = issueClient.find(IssueQuery.create().componentRoots(PROJECT_KEY)); @@ -151,35 +154,44 @@ public class IssueNotificationsTest extends AbstractIssueTest { assertThat(emails.hasNext()).isTrue(); MimeMessage message = emails.next().getMimeMessage(); assertThat(message.getHeader("To", null)).isEqualTo("<tester@example.org>"); - assertThat((String) message.getContent()).contains("Sample"); - assertThat((String) message.getContent()).contains("17 new issues (new debt: 17min)"); - assertThat((String) message.getContent()).contains("Type"); - assertThat((String) message.getContent()).contains("One Issue Per Line (xoo): 17"); - assertThat((String) message.getContent()).contains( - "More details at: http://localhost:9000/project/issues?id=sample&createdAt=2015-12-15T00%3A00%3A00%2B"); + assertThat((String) message.getContent()) + .contains("Project: Sample") + .contains("Version: " + version) + .contains("17 new issues (new debt: 17min)") + .contains("Type") + .contains("One Issue Per Line (xoo): 17") + .contains("More details at: http://localhost:9000/project/issues?id=sample&createdAt=2015-12-15T00%3A00%3A00%2B"); assertThat(emails.hasNext()).isTrue(); message = emails.next().getMimeMessage(); assertThat(message.getHeader("To", null)).isEqualTo("<tester@example.org>"); - assertThat((String) message.getContent()).contains("sample/Sample.xoo"); - assertThat((String) message.getContent()).contains("Assignee changed to Tester"); - assertThat((String) message.getContent()).contains( - "More details at: http://localhost:9000/project/issues?id=sample&issues=" + issue.key() + "&open=" + issue.key()); + assertThat((String) message.getContent()) + .contains("sample/Sample.xoo") + .contains("Assignee changed to Tester") + .contains("More details at: http://localhost:9000/project/issues?id=sample&issues=" + issue.key() + "&open=" + issue.key()); assertThat(emails.hasNext()).isFalse(); } @Test public void notifications_for_personalized_emails() throws Exception { + String version = RandomStringUtils.randomAlphanumeric(10); setServerProperty(ORCHESTRATOR, "sonar.issues.defaultAssigneeLogin", USER_LOGIN); // 1st analysis without any issue (because no file is analyzed) - runProjectAnalysis(ORCHESTRATOR, "issue/xoo-with-scm", "sonar.scm.provider", "xoo", "sonar.scm.disabled", "false", "sonar.exclusions", "**/*"); + runProjectAnalysis(ORCHESTRATOR, "issue/xoo-with-scm", + "sonar.scm.provider", "xoo", + "sonar.scm.disabled", "false", + "sonar.exclusions", "**/*", + "sonar.projectVersion", version); waitUntilAllNotificationsAreDelivered(2); assertThat(smtpServer.getMessages()).isEmpty(); // run 2nd analysis which will generate issues on the leak period - runProjectAnalysis(ORCHESTRATOR, "issue/xoo-with-scm", "sonar.scm.provider", "xoo", "sonar.scm.disabled", "false"); + runProjectAnalysis(ORCHESTRATOR, "issue/xoo-with-scm", + "sonar.scm.provider", "xoo", + "sonar.scm.disabled", "false", + "sonar.projectVersion", version); waitUntilAllNotificationsAreDelivered(2); @@ -190,6 +202,9 @@ public class IssueNotificationsTest extends AbstractIssueTest { assertThat(message.getHeader("To", null)).isEqualTo("<tester@example.org>"); assertThat(message.getSubject()).contains("You have 13 new issues"); + assertThat((String) message.getContent()) + .contains("Project: Sample") + .contains("Version: " + version); } /** |