aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server-common
diff options
context:
space:
mode:
authorAntoine Vigneau <antoine.vigneau@sonarsource.com>2024-11-27 15:42:48 +0100
committersonartech <sonartech@sonarsource.com>2024-11-29 20:03:09 +0000
commit488c8a3cce3fe721370970b04ff3cefde0f6d0b2 (patch)
tree17b0f405a9793704382719f033afb6f33aa12173 /server/sonar-server-common
parent170f39121421b369abf7fda95fb1b47f57e1362a (diff)
downloadsonarqube-488c8a3cce3fe721370970b04ff3cefde0f6d0b2.tar.gz
sonarqube-488c8a3cce3fe721370970b04ff3cefde0f6d0b2.zip
SONAR-23719 Make sure all components are using the new Email Configuration
Diffstat (limited to 'server/sonar-server-common')
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSender.java64
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java1
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java11
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplate.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/FpOrAcceptedEmailTemplate.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java14
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplate.java8
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewIssuesEmailTemplate.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java13
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/oauth/OAuthMicrosoftRestClient.java6
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplate.java10
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSenderTest.java94
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java48
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java38
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java26
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java26
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java15
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/oauth/OAuthMicrosoftRestClientTest.java4
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplateTest.java227
19 files changed, 320 insertions, 303 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSender.java b/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSender.java
index 8d1e95103f3..047590493b0 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSender.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSender.java
@@ -21,26 +21,32 @@ package org.sonar.server.email;
import java.net.MalformedURLException;
import java.time.Duration;
+import java.util.Properties;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
-import org.sonar.api.config.EmailSettings;
+import org.sonar.api.platform.Server;
+import org.sonar.server.oauth.OAuthMicrosoftRestClient;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.time.temporal.ChronoUnit.SECONDS;
-import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;
-import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_SMTP_AUTH_METHOD_OAUTH;
public abstract class EmailSender<T extends BasicEmail> {
private static final Duration SOCKET_TIMEOUT = Duration.of(30, SECONDS);
- protected final EmailSettings emailSettings;
+ protected final EmailSmtpConfiguration emailSmtpConfiguration;
+ protected final Server server;
+ private final OAuthMicrosoftRestClient oAuthMicrosoftRestClient;
- protected EmailSender(EmailSettings emailSettings) {
- this.emailSettings = emailSettings;
+ protected EmailSender(EmailSmtpConfiguration emailSmtpConfiguration, Server server, OAuthMicrosoftRestClient oAuthMicrosoftRestClient) {
+ this.emailSmtpConfiguration = emailSmtpConfiguration;
+ this.server = server;
+ this.oAuthMicrosoftRestClient = oAuthMicrosoftRestClient;
}
public void send(T report) {
@@ -68,44 +74,60 @@ public abstract class EmailSender<T extends BasicEmail> {
}
public boolean areEmailSettingsSet() {
- return isNotBlank(emailSettings.getSmtpHost());
+ return isNotBlank(emailSmtpConfiguration.getSmtpHost());
}
protected abstract void addReportContent(HtmlEmail email, T report) throws EmailException, MalformedURLException;
private void setEmailSettings(MultiPartEmail email) throws EmailException {
configureSecureConnection(email);
- email.setHostName(emailSettings.getSmtpHost());
+ email.setHostName(emailSmtpConfiguration.getSmtpHost());
email.setSocketConnectionTimeout(SOCKET_TIMEOUT);
email.setSocketTimeout(SOCKET_TIMEOUT);
email.setCharset(UTF_8.name());
- email.setFrom(emailSettings.getFrom(), emailSettings.getFromName());
+ email.setFrom(emailSmtpConfiguration.getFrom(), emailSmtpConfiguration.getFromName());
- if (isNotBlank(emailSettings.getSmtpUsername() + emailSettings.getSmtpPassword())) {
- email.setAuthentication(emailSettings.getSmtpUsername(), emailSettings.getSmtpPassword());
+ if (EMAIL_CONFIG_SMTP_AUTH_METHOD_OAUTH.equals(emailSmtpConfiguration.getAuthMethod())) {
+ setOauthAuthentication(email);
+ } else if (StringUtils.isNotBlank(emailSmtpConfiguration.getSmtpUsername()) || StringUtils.isNotBlank(emailSmtpConfiguration.getSmtpPassword())) {
+ setBasicAuthentication(email);
+ }
+ }
+
+ private void setOauthAuthentication(Email email) throws EmailException {
+ String token = oAuthMicrosoftRestClient.getAccessTokenFromClientCredentialsGrantFlow(emailSmtpConfiguration.getOAuthHost(), emailSmtpConfiguration.getOAuthClientId(),
+ emailSmtpConfiguration.getOAuthClientSecret(), emailSmtpConfiguration.getOAuthTenant(), emailSmtpConfiguration.getOAuthScope());
+ email.setAuthentication(emailSmtpConfiguration.getSmtpUsername(), token);
+ Properties props = email.getMailSession().getProperties();
+ props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
+ props.put("mail.smtp.auth.login.disable", "true");
+ props.put("mail.smtp.auth.plain.disable", "true");
+ }
+
+ private void setBasicAuthentication(Email email) {
+ if (StringUtils.isNotBlank(emailSmtpConfiguration.getSmtpUsername()) || StringUtils.isNotBlank(emailSmtpConfiguration.getSmtpPassword())) {
+ email.setAuthentication(emailSmtpConfiguration.getSmtpUsername(), emailSmtpConfiguration.getSmtpPassword());
}
}
private void configureSecureConnection(MultiPartEmail email) {
- String secureConnection = emailSettings.getSecureConnection();
- int smtpPort = emailSettings.getSmtpPort();
- if (equalsIgnoreCase(secureConnection, "ssl")) {
+ if (StringUtils.equalsIgnoreCase(emailSmtpConfiguration.getSecureConnection(), "SSLTLS")) {
email.setSSLOnConnect(true);
email.setSSLCheckServerIdentity(true);
- email.setSslSmtpPort(String.valueOf(smtpPort));
+ email.setSslSmtpPort(String.valueOf(emailSmtpConfiguration.getSmtpPort()));
// this port is not used except in EmailException message, that's why it's set with the same value than SSL port.
// It prevents from getting bad message.
- email.setSmtpPort(smtpPort);
- } else if (equalsIgnoreCase(secureConnection, "starttls")) {
+ email.setSmtpPort(emailSmtpConfiguration.getSmtpPort());
+ } else if (StringUtils.equalsIgnoreCase(emailSmtpConfiguration.getSecureConnection(), "STARTTLS")) {
email.setStartTLSEnabled(true);
email.setStartTLSRequired(true);
email.setSSLCheckServerIdentity(true);
- email.setSmtpPort(smtpPort);
- } else if (isBlank(secureConnection)) {
- email.setSmtpPort(smtpPort);
+ email.setSmtpPort(emailSmtpConfiguration.getSmtpPort());
+ } else if (StringUtils.equalsIgnoreCase(emailSmtpConfiguration.getSecureConnection(), "NONE")) {
+ email.setSmtpPort(emailSmtpConfiguration.getSmtpPort());
} else {
- throw new IllegalStateException("Unknown type of SMTP secure connection: " + secureConnection);
+ throw new IllegalStateException("Unknown type of SMTP secure connection: " + emailSmtpConfiguration.getSecureConnection());
}
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java b/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java
index 883b5ce0e49..1001da4fee1 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/email/EmailSmtpConfiguration.java
@@ -44,6 +44,7 @@ public class EmailSmtpConfiguration {
// Auth selection
public static final String EMAIL_CONFIG_SMTP_AUTH_METHOD = "email.smtp.auth.method";
public static final String EMAIL_CONFIG_SMTP_AUTH_METHOD_DEFAULT = "BASIC";
+ public static final String EMAIL_CONFIG_SMTP_AUTH_METHOD_OAUTH = "OAUTH";
// Basic Auth
public static final String EMAIL_CONFIG_SMTP_USERNAME = "email.smtp_username.secured";
public static final String EMAIL_CONFIG_SMTP_USERNAME_DEFAULT = "";
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java
index ef679e187ed..ad8cf300c6b 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/AbstractNewIssuesEmailTemplate.java
@@ -24,8 +24,8 @@ import java.net.URLEncoder;
import java.util.Date;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.api.utils.DateUtils;
import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
@@ -51,10 +51,10 @@ public abstract class AbstractNewIssuesEmailTemplate implements EmailTemplate {
static final String FIELD_BRANCH = "branch";
static final String FIELD_PULL_REQUEST = "pullRequest";
- protected final EmailSettings settings;
+ protected final Server server;
- protected AbstractNewIssuesEmailTemplate(EmailSettings settings) {
- this.settings = settings;
+ protected AbstractNewIssuesEmailTemplate(Server server) {
+ this.server = server;
}
public static String encode(String toEncode) {
@@ -175,8 +175,7 @@ public abstract class AbstractNewIssuesEmailTemplate implements EmailTemplate {
String dateString = notification.getFieldValue(FIELD_PROJECT_DATE);
if (projectKey != null && dateString != null) {
Date date = DateUtils.parseDateTime(dateString);
- String url = String.format("%s/project/issues?id=%s",
- settings.getServerBaseURL(), encode(projectKey));
+ String url = String.format("%s/project/issues?id=%s", server.getPublicRootUrl(), encode(projectKey));
String branchName = notification.getFieldValue(FIELD_BRANCH);
if (branchName != null) {
url += "&branch=" + encode(branchName);
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplate.java
index 250f17973c4..98b2fa204da 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplate.java
@@ -23,8 +23,8 @@ import com.google.common.collect.ListMultimap;
import com.google.common.collect.SetMultimap;
import java.util.List;
import javax.annotation.CheckForNull;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.core.i18n.I18n;
import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.AnalysisChange;
import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.ChangedIssue;
@@ -47,8 +47,8 @@ import static org.sonar.server.issue.notification.RuleGroup.resolveGroup;
public class ChangesOnMyIssuesEmailTemplate extends IssueChangesEmailTemplate {
private static final String NOTIFICATION_NAME_I18N_KEY = "notification.dispatcher.ChangesOnMyIssue";
- public ChangesOnMyIssuesEmailTemplate(I18n i18n, EmailSettings settings) {
- super(i18n, settings);
+ public ChangesOnMyIssuesEmailTemplate(I18n i18n, Server server) {
+ super(i18n, server);
}
@Override
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/FpOrAcceptedEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/FpOrAcceptedEmailTemplate.java
index d1169ac6540..e95758f0da6 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/FpOrAcceptedEmailTemplate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/FpOrAcceptedEmailTemplate.java
@@ -20,8 +20,8 @@
package org.sonar.server.issue.notification;
import javax.annotation.CheckForNull;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.core.i18n.I18n;
import org.sonar.server.issue.notification.FPOrAcceptedNotification.FpPrAccepted;
import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.User;
@@ -37,8 +37,8 @@ public class FpOrAcceptedEmailTemplate extends IssueChangesEmailTemplate {
private static final String NOTIFICATION_NAME_I18N_KEY = "notification.dispatcher.NewFalsePositiveIssue";
- public FpOrAcceptedEmailTemplate(I18n i18n, EmailSettings settings) {
- super(i18n, settings);
+ public FpOrAcceptedEmailTemplate(I18n i18n, Server server) {
+ super(i18n, server);
}
@Override
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java
index 8debc1f4c1e..2f44fb408ae 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/IssueChangesEmailTemplate.java
@@ -36,7 +36,7 @@ import java.util.SortedSet;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import javax.annotation.Nullable;
-import org.sonar.api.config.EmailSettings;
+import org.sonar.api.platform.Server;
import org.sonar.api.rules.RuleType;
import org.sonar.core.i18n.I18n;
import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.ChangedIssue;
@@ -74,11 +74,11 @@ public abstract class IssueChangesEmailTemplate implements EmailTemplate {
private static final String URL_ENCODED_COMMA = urlEncode(",");
private final I18n i18n;
- private final EmailSettings settings;
+ private final Server server;
- protected IssueChangesEmailTemplate(I18n i18n, EmailSettings settings) {
+ protected IssueChangesEmailTemplate(I18n i18n, Server server) {
this.i18n = i18n;
- this.settings = settings;
+ this.server = server;
}
/**
@@ -195,7 +195,7 @@ public abstract class IssueChangesEmailTemplate implements EmailTemplate {
BiConsumer<StringBuilder, Collection<ChangedIssue>> projectIssuePageHref(String projectParams) {
return (s, issues) -> {
- s.append(settings.getServerBaseURL()).append("/project/issues?").append(projectParams)
+ s.append(server.getPublicRootUrl()).append("/project/issues?").append(projectParams)
.append("&issues=");
Iterator<ChangedIssue> issueIterator = issues.iterator();
@@ -214,7 +214,7 @@ public abstract class IssueChangesEmailTemplate implements EmailTemplate {
BiConsumer<StringBuilder, Collection<ChangedIssue>> securityHotspotPageHref(String projectParams) {
return (s, issues) -> {
- s.append(settings.getServerBaseURL()).append("/security_hotspots?").append(projectParams)
+ s.append(server.getPublicRootUrl()).append("/security_hotspots?").append(projectParams)
.append("&hotspots=");
Iterator<ChangedIssue> issueIterator = issues.iterator();
@@ -246,7 +246,7 @@ public abstract class IssueChangesEmailTemplate implements EmailTemplate {
.append('"').append(i18n.message(Locale.ENGLISH, notificationI18nKey, notificationI18nKey)).append('"')
.append(" notifications from SonarQube.");
s.append(" Click ");
- link(s, s1 -> s1.append(settings.getServerBaseURL()).append("/account/notifications"), s1 -> s1.append("here"));
+ link(s, s1 -> s1.append(server.getPublicRootUrl()).append("/account/notifications"), s1 -> s1.append("here"));
s.append(" to edit your email preferences.");
s.append("</small>");
});
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplate.java
index 1669aff81cc..b4fdf58fb6e 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplate.java
@@ -20,8 +20,8 @@
package org.sonar.server.issue.notification;
import java.util.Date;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.api.utils.DateUtils;
import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
@@ -30,8 +30,8 @@ import org.sonar.server.issue.notification.NewIssuesStatistics.Metric;
*/
public class MyNewIssuesEmailTemplate extends AbstractNewIssuesEmailTemplate {
- public MyNewIssuesEmailTemplate(EmailSettings settings) {
- super(settings);
+ public MyNewIssuesEmailTemplate(Server server) {
+ super(server);
}
@Override
@@ -61,7 +61,7 @@ public class MyNewIssuesEmailTemplate extends AbstractNewIssuesEmailTemplate {
if (projectKey != null && dateString != null && assignee != null) {
Date date = DateUtils.parseDateTime(dateString);
String url = String.format("%s/project/issues?id=%s&assignees=%s",
- settings.getServerBaseURL(),
+ server.getPublicRootUrl(),
encode(projectKey),
encode(assignee));
String branchName = notification.getFieldValue(FIELD_BRANCH);
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewIssuesEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewIssuesEmailTemplate.java
index 5296f91ee41..76dd5409521 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewIssuesEmailTemplate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/notification/NewIssuesEmailTemplate.java
@@ -19,16 +19,16 @@
*/
package org.sonar.server.issue.notification;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
/**
* Creates email message for notification "new-issues".
*/
public class NewIssuesEmailTemplate extends AbstractNewIssuesEmailTemplate {
- public NewIssuesEmailTemplate(EmailSettings settings) {
- super(settings);
+ public NewIssuesEmailTemplate(Server server) {
+ super(server);
}
@Override
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java b/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java
index f4005480631..0fc971bd8f0 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java
@@ -42,13 +42,14 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.user.UserDto;
import org.sonar.server.email.EmailSmtpConfiguration;
-import org.sonar.server.oauth.OAuthMicrosoftRestClient;
import org.sonar.server.issue.notification.EmailMessage;
import org.sonar.server.issue.notification.EmailTemplate;
import org.sonar.server.notification.NotificationChannel;
+import org.sonar.server.oauth.OAuthMicrosoftRestClient;
import static java.time.temporal.ChronoUnit.SECONDS;
import static java.util.Objects.requireNonNull;
+import static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_SMTP_AUTH_METHOD_OAUTH;
/**
* References:
@@ -99,18 +100,20 @@ public class EmailNotificationChannel extends NotificationChannel {
private static final String SUBJECT_DEFAULT = "Notification";
private static final String SMTP_HOST_NOT_CONFIGURED_DEBUG_MSG = "SMTP host was not configured - email will not be sent";
private static final String MAIL_SENT_FROM = "%sMail sent from: %s";
- private static final String OAUTH_AUTH_METHOD = "OAUTH";
private final EmailSmtpConfiguration configuration;
private final Server server;
private final EmailTemplate[] templates;
private final DbClient dbClient;
+ private final OAuthMicrosoftRestClient oAuthMicrosoftRestClient;
- public EmailNotificationChannel(EmailSmtpConfiguration configuration, Server server, EmailTemplate[] templates, DbClient dbClient) {
+ public EmailNotificationChannel(EmailSmtpConfiguration configuration, Server server, EmailTemplate[] templates, DbClient dbClient,
+ OAuthMicrosoftRestClient oAuthMicrosoftRestClient) {
this.configuration = configuration;
this.server = server;
this.templates = templates;
this.dbClient = dbClient;
+ this.oAuthMicrosoftRestClient = oAuthMicrosoftRestClient;
}
public boolean isActivated() {
@@ -297,7 +300,7 @@ public class EmailNotificationChannel extends NotificationChannel {
configureSecureConnection(email);
email.setSocketConnectionTimeout(SOCKET_TIMEOUT);
email.setSocketTimeout(SOCKET_TIMEOUT);
- if (OAUTH_AUTH_METHOD.equals(configuration.getAuthMethod())) {
+ if (EMAIL_CONFIG_SMTP_AUTH_METHOD_OAUTH.equals(configuration.getAuthMethod())) {
setOauthAuthentication(email);
} else if (StringUtils.isNotBlank(configuration.getSmtpUsername()) || StringUtils.isNotBlank(configuration.getSmtpPassword())) {
setBasicAuthentication(email);
@@ -305,7 +308,7 @@ public class EmailNotificationChannel extends NotificationChannel {
}
private void setOauthAuthentication(Email email) throws EmailException {
- String token = OAuthMicrosoftRestClient.getAccessTokenFromClientCredentialsGrantFlow(configuration.getOAuthHost(), configuration.getOAuthClientId(),
+ String token = oAuthMicrosoftRestClient.getAccessTokenFromClientCredentialsGrantFlow(configuration.getOAuthHost(), configuration.getOAuthClientId(),
configuration.getOAuthClientSecret(), configuration.getOAuthTenant(), configuration.getOAuthScope());
email.setAuthentication(configuration.getSmtpUsername(), token);
Properties props = email.getMailSession().getProperties();
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/oauth/OAuthMicrosoftRestClient.java b/server/sonar-server-common/src/main/java/org/sonar/server/oauth/OAuthMicrosoftRestClient.java
index 3a7ada75440..24311990824 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/oauth/OAuthMicrosoftRestClient.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/oauth/OAuthMicrosoftRestClient.java
@@ -26,11 +26,7 @@ import java.util.concurrent.ExecutionException;
public class OAuthMicrosoftRestClient {
- private OAuthMicrosoftRestClient() {
- // Only static method
- }
-
- public static String getAccessTokenFromClientCredentialsGrantFlow(String host, String clientId, String clientSecret, String tenant, String scope) {
+ public String getAccessTokenFromClientCredentialsGrantFlow(String host, String clientId, String clientSecret, String tenant, String scope) {
final OAuth20Service service = new ServiceBuilder(clientId)
.apiSecret(clientSecret)
.defaultScope(scope)
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplate.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplate.java
index f7abea14a29..9a7d1706b6a 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplate.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplate.java
@@ -23,9 +23,9 @@ import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.measures.Metric;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.server.issue.notification.EmailMessage;
import org.sonar.server.issue.notification.EmailTemplate;
import org.sonar.server.measure.Rating;
@@ -37,10 +37,10 @@ import org.sonar.server.measure.Rating;
*/
public class QGChangeEmailTemplate implements EmailTemplate {
- private final EmailSettings configuration;
+ private final Server server;
- public QGChangeEmailTemplate(EmailSettings configuration) {
- this.configuration = configuration;
+ public QGChangeEmailTemplate( Server server) {
+ this.server = server;
}
@Override
@@ -123,7 +123,7 @@ public class QGChangeEmailTemplate implements EmailTemplate {
}
}
- messageBody.append("\n").append("More details at: ").append(configuration.getServerBaseURL()).append("/dashboard?id=").append(projectKey);
+ messageBody.append("\n").append("More details at: ").append(server.getPublicRootUrl()).append("/dashboard?id=").append(projectKey);
if (branchName != null) {
messageBody.append("&branch=").append(branchName);
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSenderTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSenderTest.java
index 299bbb4b293..e8c549d2667 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSenderTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/email/EmailSenderTest.java
@@ -19,13 +19,13 @@
*/
package org.sonar.server.email;
-import java.net.MalformedURLException;
+import java.util.Properties;
import java.util.Set;
-import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
import org.junit.Test;
-import org.sonar.api.config.EmailSettings;
+import org.sonar.api.platform.Server;
+import org.sonar.server.oauth.OAuthMicrosoftRestClient;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;
@@ -33,11 +33,15 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_SMTP_AUTH_METHOD_OAUTH;
+import static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_SMTP_OAUTH_SCOPE_DEFAULT;
public class EmailSenderTest {
- private EmailSettings emailSettings = mock(EmailSettings.class);
- private EmailSender<BasicEmail> sender = new EmailSender<>(emailSettings) {
- @Override protected void addReportContent(HtmlEmail email, BasicEmail report) throws EmailException, MalformedURLException {
+ private final EmailSmtpConfiguration emailSmtpConfiguration = mock();
+ private final Server server = mock();
+ private final OAuthMicrosoftRestClient oAuthMicrosoftRestClient = mock();
+ private final EmailSender<BasicEmail> sender = new EmailSender<>(emailSmtpConfiguration, server, oAuthMicrosoftRestClient) {
+ @Override protected void addReportContent(HtmlEmail email, BasicEmail report) {
email.setSubject("Email Subject");
}
};
@@ -45,13 +49,14 @@ public class EmailSenderTest {
@Test
public void test_email_fields() throws Exception {
BasicEmail basicEmail = new BasicEmail(Set.of("noreply@nowhere"));
- when(emailSettings.getSmtpHost()).thenReturn("smtphost");
- when(emailSettings.getSmtpPort()).thenReturn(25);
- when(emailSettings.getFrom()).thenReturn("noreply@nowhere");
- when(emailSettings.getFromName()).thenReturn("My SonarQube");
- when(emailSettings.getPrefix()).thenReturn("[SONAR]");
- when(emailSettings.getSmtpUsername()).thenReturn("");
- when(emailSettings.getSmtpPassword()).thenReturn("");
+ when(emailSmtpConfiguration.getSmtpHost()).thenReturn("smtphost");
+ when(emailSmtpConfiguration.getSmtpPort()).thenReturn(25);
+ when(emailSmtpConfiguration.getSecureConnection()).thenReturn("NONE");
+ when(emailSmtpConfiguration.getFrom()).thenReturn("noreply@nowhere");
+ when(emailSmtpConfiguration.getFromName()).thenReturn("My SonarQube");
+ when(emailSmtpConfiguration.getPrefix()).thenReturn("[SONAR]");
+ when(emailSmtpConfiguration.getSmtpUsername()).thenReturn("");
+ when(emailSmtpConfiguration.getSmtpPassword()).thenReturn("");
MultiPartEmail email = sender.createEmail(basicEmail);
@@ -71,9 +76,10 @@ public class EmailSenderTest {
@Test
public void support_empty_body() throws Exception {
BasicEmail basicEmail = new BasicEmail(Set.of("noreply@nowhere"));
- when(emailSettings.getSmtpHost()).thenReturn("smtphost");
- when(emailSettings.getSmtpPort()).thenReturn(465);
- when(emailSettings.getFrom()).thenReturn("noreply@nowhere");
+ when(emailSmtpConfiguration.getSmtpHost()).thenReturn("smtphost");
+ when(emailSmtpConfiguration.getSmtpPort()).thenReturn(465);
+ when(emailSmtpConfiguration.getSecureConnection()).thenReturn("NONE");
+ when(emailSmtpConfiguration.getFrom()).thenReturn("noreply@nowhere");
MultiPartEmail email = sender.createEmail(basicEmail);
@@ -83,12 +89,12 @@ public class EmailSenderTest {
@Test
public void support_ssl() throws Exception {
BasicEmail basicEmail = new BasicEmail(Set.of("noreply@nowhere"));
- when(emailSettings.getSecureConnection()).thenReturn("SSL");
- when(emailSettings.getSmtpHost()).thenReturn("smtphost");
- when(emailSettings.getSmtpPort()).thenReturn(466);
- when(emailSettings.getFrom()).thenReturn("noreply@nowhere");
- when(emailSettings.getSmtpUsername()).thenReturn("login");
- when(emailSettings.getSmtpPassword()).thenReturn("pwd");
+ when(emailSmtpConfiguration.getSecureConnection()).thenReturn("SSLTLS");
+ when(emailSmtpConfiguration.getSmtpHost()).thenReturn("smtphost");
+ when(emailSmtpConfiguration.getSmtpPort()).thenReturn(466);
+ when(emailSmtpConfiguration.getFrom()).thenReturn("noreply@nowhere");
+ when(emailSmtpConfiguration.getSmtpUsername()).thenReturn("login");
+ when(emailSmtpConfiguration.getSmtpPassword()).thenReturn("pwd");
MultiPartEmail email = sender.createEmail(basicEmail);
@@ -103,12 +109,12 @@ public class EmailSenderTest {
@Test
public void support_starttls() throws Exception {
BasicEmail basicEmail = new BasicEmail(Set.of("noreply@nowhere"));
- when(emailSettings.getSecureConnection()).thenReturn("STARTTLS");
- when(emailSettings.getSmtpHost()).thenReturn("smtphost");
- when(emailSettings.getSmtpPort()).thenReturn(587);
- when(emailSettings.getFrom()).thenReturn("noreply@nowhere");
- when(emailSettings.getSmtpUsername()).thenReturn("login");
- when(emailSettings.getSmtpPassword()).thenReturn("pwd");
+ when(emailSmtpConfiguration.getSecureConnection()).thenReturn("STARTTLS");
+ when(emailSmtpConfiguration.getSmtpHost()).thenReturn("smtphost");
+ when(emailSmtpConfiguration.getSmtpPort()).thenReturn(587);
+ when(emailSmtpConfiguration.getFrom()).thenReturn("noreply@nowhere");
+ when(emailSmtpConfiguration.getSmtpUsername()).thenReturn("login");
+ when(emailSmtpConfiguration.getSmtpPassword()).thenReturn("pwd");
MultiPartEmail email = sender.createEmail(basicEmail);
@@ -120,6 +126,38 @@ public class EmailSenderTest {
}
@Test
+ public void support_oauth() throws Exception {
+ BasicEmail basicEmail = new BasicEmail(Set.of("noreply@nowhere"));
+ when(emailSmtpConfiguration.getSecureConnection()).thenReturn("STARTTLS");
+ when(emailSmtpConfiguration.getSmtpHost()).thenReturn("smtphost");
+ when(emailSmtpConfiguration.getSmtpPort()).thenReturn(587);
+ when(emailSmtpConfiguration.getFrom()).thenReturn("noreply@nowhere");
+ when(emailSmtpConfiguration.getAuthMethod()).thenReturn(EMAIL_CONFIG_SMTP_AUTH_METHOD_OAUTH);
+ when(emailSmtpConfiguration.getSmtpUsername()).thenReturn("login");
+ when(emailSmtpConfiguration.getSmtpPassword()).thenReturn("pwd");
+ when(emailSmtpConfiguration.getOAuthHost()).thenReturn("oauthHost");
+ when(emailSmtpConfiguration.getOAuthClientId()).thenReturn("oauthClientId");
+ when(emailSmtpConfiguration.getOAuthClientSecret()).thenReturn("oauthClientSecret");
+ when(emailSmtpConfiguration.getOAuthTenant()).thenReturn("oauthTenant");
+ when(emailSmtpConfiguration.getOAuthScope()).thenReturn(EMAIL_CONFIG_SMTP_OAUTH_SCOPE_DEFAULT);
+ when(oAuthMicrosoftRestClient.getAccessTokenFromClientCredentialsGrantFlow("oauthHost", "oauthClientId", "oauthClientSecret", "oauthTenant",
+ EMAIL_CONFIG_SMTP_OAUTH_SCOPE_DEFAULT)).thenReturn("token");
+
+ MultiPartEmail email = sender.createEmail(basicEmail);
+
+ assertThat(email.isSSLOnConnect()).isFalse();
+ assertThat(email.isStartTLSEnabled()).isTrue();
+ assertThat(email.isStartTLSRequired()).isTrue();
+ assertThat(email.getHostName()).isEqualTo("smtphost");
+ assertThat(email.getSmtpPort()).isEqualTo("587");
+ Properties emailProperties = email.getMailSession().getProperties();
+ assertThat(emailProperties)
+ .containsEntry("mail.smtp.auth.mechanisms", "XOAUTH2")
+ .containsEntry("mail.smtp.auth.login.disable", "true")
+ .containsEntry("mail.smtp.auth.plain.disable", "true");
+ }
+
+ @Test
public void send_email() throws Exception {
HtmlEmail email = mock(HtmlEmail.class);
BasicEmail basicEmail = new BasicEmail(Set.of("noreply@nowhere"));
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java
index 009ed3c2d2d..e8150810402 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/ChangesOnMyIssuesEmailTemplateTest.java
@@ -35,8 +35,8 @@ import java.util.stream.Stream;
import org.elasticsearch.common.util.set.Sets;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.api.rules.RuleType;
import org.sonar.core.i18n.I18n;
import org.sonar.server.issue.notification.IssuesChangesNotificationBuilder.AnalysisChange;
@@ -82,9 +82,9 @@ public class ChangesOnMyIssuesEmailTemplateTest {
private static final String[] SECURITY_HOTSPOTS_STATUSES = {STATUS_TO_REVIEW, STATUS_REVIEWED};
- private I18n i18n = mock(I18n.class);
- private EmailSettings emailSettings = mock(EmailSettings.class);
- private ChangesOnMyIssuesEmailTemplate underTest = new ChangesOnMyIssuesEmailTemplate(i18n, emailSettings);
+ private final I18n i18n = mock(I18n.class);
+ private final Server server = mock();
+ private final ChangesOnMyIssuesEmailTemplate underTest = new ChangesOnMyIssuesEmailTemplate(i18n, server);
@Test
public void format_returns_null_on_Notification() {
@@ -311,7 +311,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
String host = secure().nextAlphabetic(15);
when(i18n.message(Locale.ENGLISH, "notification.dispatcher.ChangesOnMyIssue", "notification.dispatcher.ChangesOnMyIssue"))
.thenReturn(wordingNotification);
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
Project project = newProject("foo");
Rule rule = newRule("bar", ruleType);
Set<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(4))
@@ -397,7 +397,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
String host = secure().nextAlphabetic(15);
ChangedIssue changedIssue = newChangedIssue("key", randomValidStatus(), project, ruleName, randomRuleTypeHotspotExcluded());
AnalysisChange analysisChange = newAnalysisChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(analysisChange, ImmutableSet.of(changedIssue)));
@@ -418,9 +418,9 @@ public class ChangesOnMyIssuesEmailTemplateTest {
Rule rule = newRule(ruleName, randomRuleTypeHotspotExcluded());
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, randomValidStatus(), project, rule))
- .collect(toList());
+ .toList();
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));
@@ -449,7 +449,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
String host = secure().nextAlphabetic(15);
ChangedIssue changedIssue = newChangedIssue("key", randomValidStatus(), project, ruleName, randomRuleTypeHotspotExcluded());
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.of(changedIssue)));
@@ -471,7 +471,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
String key = "key";
ChangedIssue changedIssue = newChangedIssue(key, randomValidStatus(), project, ruleName, randomRuleTypeHotspotExcluded());
AnalysisChange analysisChange = newAnalysisChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(analysisChange, ImmutableSet.of(changedIssue)));
@@ -494,7 +494,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
String key = "key";
ChangedIssue changedIssue = newChangedIssue(key, randomValidStatus(), project, ruleName, randomRuleTypeHotspotExcluded());
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.of(changedIssue)));
@@ -517,9 +517,9 @@ public class ChangesOnMyIssuesEmailTemplateTest {
String issueStatus = randomValidStatus();
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, issueStatus, project, rule))
- .collect(toList());
+ .toList();
AnalysisChange analysisChange = newAnalysisChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(analysisChange, ImmutableSet.copyOf(changedIssues)));
@@ -543,9 +543,9 @@ public class ChangesOnMyIssuesEmailTemplateTest {
Rule rule = newRule(ruleName, randomRuleTypeHotspotExcluded());
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, randomValidStatus(), project, rule))
- .collect(toList());
+ .toList();
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));
@@ -571,9 +571,9 @@ public class ChangesOnMyIssuesEmailTemplateTest {
String status = randomValidStatus();
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, status, project, rule))
- .collect(toList());
+ .toList();
AnalysisChange analysisChange = newAnalysisChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(analysisChange, ImmutableSet.copyOf(changedIssues)));
@@ -598,9 +598,9 @@ public class ChangesOnMyIssuesEmailTemplateTest {
Rule rule = newRandomNotAHotspotRule(ruleName);
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, randomValidStatus(), project, rule))
- .collect(toList());
+ .toList();
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));
@@ -630,7 +630,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
.collect(toList());
Collections.shuffle(changedIssues);
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));
@@ -667,7 +667,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
.collect(toList());
Collections.shuffle(changedIssues);
AnalysisChange analysisChange = newAnalysisChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(analysisChange, ImmutableSet.copyOf(changedIssues)));
@@ -702,7 +702,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
.collect(toList());
Collections.shuffle(changedIssues);
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));
@@ -745,7 +745,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
Collections.shuffle(changedIssues);
AnalysisChange analysisChange = newAnalysisChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(analysisChange, ImmutableSet.copyOf(changedIssues)));
@@ -808,7 +808,7 @@ public class ChangesOnMyIssuesEmailTemplateTest {
.collect(toList());
Collections.shuffle(changedIssues);
UserChange userChange = newUserChange();
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new ChangesOnMyIssuesNotification(userChange, ImmutableSet.copyOf(changedIssues)));
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java
index 967e5955cd8..68b26b62290 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/FpPrAcceptedEmailTemplateTest.java
@@ -32,8 +32,8 @@ import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleType;
import org.sonar.core.i18n.I18n;
@@ -63,8 +63,8 @@ import static org.sonar.server.issue.notification.IssuesChangesNotificationBuild
@RunWith(DataProviderRunner.class)
public class FpPrAcceptedEmailTemplateTest {
private final I18n i18n = mock(I18n.class);
- private final EmailSettings emailSettings = mock(EmailSettings.class);
- private final FpOrAcceptedEmailTemplate underTest = new FpOrAcceptedEmailTemplate(i18n, emailSettings);
+ private final Server server = mock();
+ private final FpOrAcceptedEmailTemplate underTest = new FpOrAcceptedEmailTemplate(i18n, server);
private static final long DATE_LONG = Instant.now().toEpochMilli();
@@ -144,7 +144,7 @@ public class FpPrAcceptedEmailTemplateTest {
String host = secure().nextAlphabetic(15);
when(i18n.message(Locale.ENGLISH, "notification.dispatcher.NewFalsePositiveIssue", "notification.dispatcher.NewFalsePositiveIssue"))
.thenReturn(wordingNotification);
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, Collections.emptySet(), fpPrAccepted));
@@ -169,7 +169,7 @@ public class FpPrAcceptedEmailTemplateTest {
String ruleName = secure().nextAlphabetic(8);
String host = secure().nextAlphabetic(15);
ChangedIssue changedIssue = newChangedIssue("key", project, ruleName, randomRuleTypeHotspotExcluded());
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.of(changedIssue), fpPrAccepted));
@@ -189,7 +189,7 @@ public class FpPrAcceptedEmailTemplateTest {
String ruleName = secure().nextAlphabetic(8);
String host = secure().nextAlphabetic(15);
ChangedIssue changedIssue = newChangedIssue("key", project, ruleName, SECURITY_HOTSPOT);
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.of(changedIssue), fpPrAccepted));
@@ -211,7 +211,7 @@ public class FpPrAcceptedEmailTemplateTest {
String host = secure().nextAlphabetic(15);
String key = "key";
ChangedIssue changedIssue = newChangedIssue(key, project, ruleName, randomRuleTypeHotspotExcluded());
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.of(changedIssue), fpPrAccepted));
@@ -234,7 +234,7 @@ public class FpPrAcceptedEmailTemplateTest {
String host = secure().nextAlphabetic(15);
String key = "key";
ChangedIssue changedIssue = newChangedIssue(key, project, ruleName, SECURITY_HOTSPOT);
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.of(changedIssue), fpPrAccepted));
@@ -257,8 +257,8 @@ public class FpPrAcceptedEmailTemplateTest {
Rule rule = newRandomNotAHotspotRule(ruleName);
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, project, rule))
- .collect(toList());
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ .toList();
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.copyOf(changedIssues), fpPrAccepted));
@@ -283,8 +283,8 @@ public class FpPrAcceptedEmailTemplateTest {
Rule rule = newSecurityHotspotRule(ruleName);
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, project, rule))
- .collect(toList());
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ .toList();
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.copyOf(changedIssues), fpPrAccepted));
@@ -310,8 +310,8 @@ public class FpPrAcceptedEmailTemplateTest {
Rule rule = newRandomNotAHotspotRule(ruleName);
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, project, rule))
- .collect(toList());
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ .toList();
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.copyOf(changedIssues), fpPrAccepted));
@@ -337,8 +337,8 @@ public class FpPrAcceptedEmailTemplateTest {
Rule rule = newSecurityHotspotRule(ruleName);
List<ChangedIssue> changedIssues = IntStream.range(0, 2 + new Random().nextInt(5))
.mapToObj(i -> newChangedIssue("issue_" + i, project, rule))
- .collect(toList());
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ .toList();
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.copyOf(changedIssues), fpPrAccepted));
@@ -368,7 +368,7 @@ public class FpPrAcceptedEmailTemplateTest {
.map(project -> newChangedIssue("issue_" + project.getUuid(), project, newRandomNotAHotspotRule(secure().nextAlphabetic(2))))
.collect(toList());
Collections.shuffle(changedIssues);
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.copyOf(changedIssues), fpPrAccepted));
@@ -403,7 +403,7 @@ public class FpPrAcceptedEmailTemplateTest {
.map(rule -> newChangedIssue("issue_" + rule.getName(), project, rule))
.collect(toList());
Collections.shuffle(changedIssues);
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.copyOf(changedIssues), fpPrAccepted));
@@ -436,7 +436,7 @@ public class FpPrAcceptedEmailTemplateTest {
.flatMap(t -> t)
.collect(toList());
Collections.shuffle(changedIssues);
- when(emailSettings.getServerBaseURL()).thenReturn(host);
+ when(server.getPublicRootUrl()).thenReturn(host);
EmailMessage emailMessage = underTest.format(new FPOrAcceptedNotification(change, ImmutableSet.copyOf(changedIssues), fpPrAccepted));
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java
index e91c59de41d..39bb7cc07f9 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/MyNewIssuesEmailTemplateTest.java
@@ -19,13 +19,8 @@
*/
package org.sonar.server.issue.notification;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.config.EmailSettings;
-import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.notifications.Notification;
import org.sonar.api.platform.Server;
@@ -39,10 +34,8 @@ import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.TAG
public class MyNewIssuesEmailTemplateTest {
- private MapSettings settings = new MapSettings();
-
- private Server server = mock(Server.class);
- private MyNewIssuesEmailTemplate underTest = new MyNewIssuesEmailTemplate(new EmailSettings(settings.asConfig(), server));
+ private final Server server = mock(Server.class);
+ private final MyNewIssuesEmailTemplate underTest = new MyNewIssuesEmailTemplate(server);
@Before
public void setUp() {
@@ -65,7 +58,6 @@ public class MyNewIssuesEmailTemplateTest {
EmailMessage message = underTest.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
@@ -121,7 +113,6 @@ public class MyNewIssuesEmailTemplateTest {
EmailMessage message = underTest.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
Version: 52.0
@@ -139,7 +130,6 @@ public class MyNewIssuesEmailTemplateTest {
EmailMessage message = underTest.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
Branch: feature1
@@ -169,7 +159,6 @@ public class MyNewIssuesEmailTemplateTest {
EmailMessage message = underTest.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
Branch: feature1
@@ -222,15 +211,4 @@ public class MyNewIssuesEmailTemplateTest {
.setFieldValue(RULE + ".2.count", "5");
}
- private void assertStartsWithFile(String message, String resourcePath) throws IOException {
- String fileContent = IOUtils.toString(getClass().getResource(resourcePath), StandardCharsets.UTF_8);
- assertThat(sanitizeString(message)).startsWith(sanitizeString(fileContent));
- }
-
- /**
- * sanitize EOL and tabs if git clone is badly configured
- */
- private static String sanitizeString(String s) {
- return s.replaceAll("\\r\\n|\\r|\\s+", "");
- }
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java
index 413b9bcfbf7..3fa7f1d44ec 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/notification/NewIssuesEmailTemplateTest.java
@@ -19,13 +19,8 @@
*/
package org.sonar.server.issue.notification;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.config.EmailSettings;
-import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.notifications.Notification;
import org.sonar.api.platform.Server;
@@ -40,10 +35,8 @@ import static org.sonar.server.issue.notification.NewIssuesStatistics.Metric.TAG
public class NewIssuesEmailTemplateTest {
- private MapSettings settings = new MapSettings();
-
- private Server server = mock(Server.class);
- private NewIssuesEmailTemplate template = new NewIssuesEmailTemplate(new EmailSettings(settings.asConfig(), server));
+ private final Server server = mock(Server.class);
+ private final NewIssuesEmailTemplate template = new NewIssuesEmailTemplate(server);
@Before
public void setUp() {
@@ -96,7 +89,6 @@ public class NewIssuesEmailTemplateTest {
EmailMessage message = template.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
Version: 42.1.1
@@ -128,7 +120,6 @@ public class NewIssuesEmailTemplateTest {
EmailMessage message = template.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
@@ -156,7 +147,6 @@ public class NewIssuesEmailTemplateTest {
EmailMessage message = template.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
Branch: feature1
@@ -174,7 +164,6 @@ public class NewIssuesEmailTemplateTest {
EmailMessage message = template.format(notification);
- // TODO datetime to be completed when test is isolated from JVM timezone
assertThat(message.getMessage()).startsWith("""
Project: Struts
Branch: feature1
@@ -236,15 +225,4 @@ public class NewIssuesEmailTemplateTest {
.setFieldValue(RULE + ".2.count", "5");
}
- private void assertStartsWithFile(String message, String resourcePath) throws IOException {
- String fileContent = IOUtils.toString(getClass().getResource(resourcePath), StandardCharsets.UTF_8);
- assertThat(sanitizeString(message)).startsWith(sanitizeString(fileContent));
- }
-
- /**
- * sanitize EOL and tabs if git clone is badly configured
- */
- private static String sanitizeString(String s) {
- return s.replaceAll("\\r\\n|\\r|\\s+", "");
- }
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java
index 750fdff9f10..64ad508a0fd 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/notification/email/EmailNotificationChannelTest.java
@@ -47,6 +47,7 @@ import org.sonar.server.email.EmailSmtpConfiguration;
import org.sonar.server.issue.notification.EmailMessage;
import org.sonar.server.issue.notification.EmailTemplate;
import org.sonar.server.notification.email.EmailNotificationChannel.EmailDeliveryRequest;
+import org.sonar.server.oauth.OAuthMicrosoftRestClient;
import org.subethamail.wiser.Wiser;
import org.subethamail.wiser.WiserMessage;
@@ -83,7 +84,7 @@ public class EmailNotificationChannelTest {
configuration = mock(EmailSmtpConfiguration.class);
server = mock(Server.class);
- underTest = new EmailNotificationChannel(configuration, server, null, null);
+ underTest = new EmailNotificationChannel(configuration, server, null, null, mock(OAuthMicrosoftRestClient.class));
}
@After
@@ -256,7 +257,7 @@ public class EmailNotificationChannelTest {
@Test
public void deliverAll_has_no_effect_if_set_is_empty() {
EmailSmtpConfiguration emailSettings = mock(EmailSmtpConfiguration.class);
- EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(emailSettings, server, null, null);
+ EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(emailSettings, server, null, null, mock(OAuthMicrosoftRestClient.class));
int count = emailNotificationChannel.deliverAll(Collections.emptySet());
@@ -272,7 +273,7 @@ public class EmailNotificationChannelTest {
Set<EmailDeliveryRequest> requests = IntStream.range(0, 1 + new Random().nextInt(10))
.mapToObj(i -> new EmailDeliveryRequest("foo" + i + "@moo", mock(Notification.class)))
.collect(toSet());
- EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(emailSettings, server, null, null);
+ EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(emailSettings, server, null, null, mock(OAuthMicrosoftRestClient.class));
int count = emailNotificationChannel.deliverAll(requests);
@@ -290,7 +291,7 @@ public class EmailNotificationChannelTest {
Set<EmailDeliveryRequest> requests = IntStream.range(0, 1 + new Random().nextInt(10))
.mapToObj(i -> new EmailDeliveryRequest(emptyString, mock(Notification.class)))
.collect(toSet());
- EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(emailSettings, server, null, null);
+ EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(emailSettings, server, null, null, mock(OAuthMicrosoftRestClient.class));
int count = emailNotificationChannel.deliverAll(requests);
@@ -316,7 +317,8 @@ public class EmailNotificationChannelTest {
Set<EmailDeliveryRequest> requests = Stream.of(notification1, notification2, notification3)
.map(t -> new EmailDeliveryRequest(recipientEmail, t))
.collect(toSet());
- EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(configuration, server, new EmailTemplate[] {template1, template3}, null);
+ EmailNotificationChannel emailNotificationChannel =
+ new EmailNotificationChannel(configuration, server, new EmailTemplate[] {template1, template3}, null, mock(OAuthMicrosoftRestClient.class));
int count = emailNotificationChannel.deliverAll(requests);
@@ -356,7 +358,8 @@ public class EmailNotificationChannelTest {
when(template11.format(notification1)).thenReturn(emailMessage11);
when(template12.format(notification1)).thenReturn(emailMessage12);
EmailDeliveryRequest request = new EmailDeliveryRequest(recipientEmail, notification1);
- EmailNotificationChannel emailNotificationChannel = new EmailNotificationChannel(configuration, server, new EmailTemplate[] {template11, template12}, null);
+ EmailNotificationChannel emailNotificationChannel =
+ new EmailNotificationChannel(configuration, server, new EmailTemplate[] {template11, template12}, null, mock(OAuthMicrosoftRestClient.class));
int count = emailNotificationChannel.deliverAll(Collections.singleton(request));
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/oauth/OAuthMicrosoftRestClientTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/oauth/OAuthMicrosoftRestClientTest.java
index 39e796d41a8..b80fd60b923 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/oauth/OAuthMicrosoftRestClientTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/oauth/OAuthMicrosoftRestClientTest.java
@@ -25,9 +25,11 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
class OAuthMicrosoftRestClientTest {
+ private final OAuthMicrosoftRestClient underTest = new OAuthMicrosoftRestClient();
+
@Test
void getAccessTokenFromClientCredentialsGrantFlow_throwsException() {
- assertThatThrownBy(() -> OAuthMicrosoftRestClient.getAccessTokenFromClientCredentialsGrantFlow("https://localhost", "clientId", "clientSecret", "tenant", "scope"))
+ assertThatThrownBy(() -> underTest.getAccessTokenFromClientCredentialsGrantFlow("https://localhost", "clientId", "clientSecret", "tenant", "scope"))
.isInstanceOf(IllegalStateException.class)
.hasMessageStartingWith("Unable to get a token: ");
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplateTest.java
index 0194d39635d..6fa0780aa40 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplateTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/notification/QGChangeEmailTemplateTest.java
@@ -25,52 +25,49 @@ import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
+import org.sonar.api.platform.Server;
import org.sonar.server.issue.notification.EmailMessage;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(DataProviderRunner.class)
public class QGChangeEmailTemplateTest {
- private QGChangeEmailTemplate template;
+ private final Server server = mock();
+ private final QGChangeEmailTemplate underTest = new QGChangeEmailTemplate(server);
@Before
public void setUp() {
- EmailSettings configuration = mock(EmailSettings.class);
- when(configuration.getServerBaseURL()).thenReturn("http://nemo.sonarsource.org");
- template = new QGChangeEmailTemplate(configuration);
+ when(server.getPublicRootUrl()).thenReturn("http://nemo.sonarsource.org");
}
@Test
public void shouldNotFormatIfNotCorrectNotification() {
Notification notification = new Notification("other-notif");
- EmailMessage message = template.format(notification);
- assertThat(message, nullValue());
+ EmailMessage message = underTest.format(notification);
+ assertThat(message).isNull();
}
@Test
public void shouldFormatAlertWithSeveralMessages() {
Notification notification = createNotification("Failed", "violations > 4, coverage < 75%", "ERROR", "false");
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("Quality gate status changed on \"Foo\""));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Failed\n" +
- "\n" +
- "Quality gate thresholds:\n" +
- " - violations > 4\n" +
- " - coverage < 75%\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("Quality gate status changed on \"Foo\"");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Version: V1-SNAP
+ Quality gate status: Failed
+
+ Quality gate thresholds:
+ - violations > 4
+ - coverage < 75%
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo""");
}
@Test
@@ -78,56 +75,56 @@ public class QGChangeEmailTemplateTest {
Notification notification = createNotification("Failed", "violations > 4, coverage < 75%", "ERROR", "false")
.setFieldValue("branch", "feature");
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("Quality gate status changed on \"Foo (feature)\""));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Branch: feature\n" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Failed\n" +
- "\n" +
- "Quality gate thresholds:\n" +
- " - violations > 4\n" +
- " - coverage < 75%\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("Quality gate status changed on \"Foo (feature)\"");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Branch: feature
+ Version: V1-SNAP
+ Quality gate status: Failed
+
+ Quality gate thresholds:
+ - violations > 4
+ - coverage < 75%
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature""");
}
@Test
public void shouldFormatNewAlertWithSeveralMessages() {
Notification notification = createNotification("Failed", "violations > 4, coverage < 75%", "ERROR", "true");
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("New quality gate threshold reached on \"Foo\""));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Failed\n" +
- "\n" +
- "New quality gate thresholds:\n" +
- " - violations > 4\n" +
- " - coverage < 75%\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("New quality gate threshold reached on \"Foo\"");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Version: V1-SNAP
+ Quality gate status: Failed
+
+ New quality gate thresholds:
+ - violations > 4
+ - coverage < 75%
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo""");
}
@Test
public void shouldFormatNewAlertWithOneMessage() {
Notification notification = createNotification("Failed", "violations > 4", "ERROR", "true");
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("New quality gate threshold reached on \"Foo\""));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Failed\n" +
- "\n" +
- "New quality gate threshold: violations > 4\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("New quality gate threshold reached on \"Foo\"");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Version: V1-SNAP
+ Quality gate status: Failed
+
+ New quality gate threshold: violations > 4
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo""");
}
@Test
@@ -135,32 +132,32 @@ public class QGChangeEmailTemplateTest {
Notification notification = createNotification("Failed", "violations > 4", "ERROR", "true")
.setFieldValue("projectVersion", null);
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("New quality gate threshold reached on \"Foo\""));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Quality gate status: Failed\n" +
- "\n" +
- "New quality gate threshold: violations > 4\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("New quality gate threshold reached on \"Foo\"");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Quality gate status: Failed
+
+ New quality gate threshold: violations > 4
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo""");
}
@Test
public void shouldFormatBackToGreenMessage() {
Notification notification = createNotification("Passed", "", "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" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Passed\n" +
- "\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("\"Foo\" is back to green");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Version: V1-SNAP
+ Quality gate status: Passed
+
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo""");
}
@Test
@@ -168,18 +165,18 @@ public class QGChangeEmailTemplateTest {
Notification notification = createNotification("Failed", "violations > 4", "ERROR", "true")
.setFieldValue("branch", "feature");
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("New quality gate threshold reached on \"Foo (feature)\""));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Branch: feature\n" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Failed\n" +
- "\n" +
- "New quality gate threshold: violations > 4\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("New quality gate threshold reached on \"Foo (feature)\"");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Branch: feature
+ Version: V1-SNAP
+ Quality gate status: Failed
+
+ New quality gate threshold: violations > 4
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature""");
}
@Test
@@ -187,17 +184,17 @@ public class QGChangeEmailTemplateTest {
Notification notification = createNotification("Passed", "", "OK", "false")
.setFieldValue("branch", "feature");
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("\"Foo (feature)\" is back to green"));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Branch: feature\n" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Passed\n" +
- "\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("\"Foo (feature)\" is back to green");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Branch: feature
+ Version: V1-SNAP
+ Quality gate status: Passed
+
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo&branch=feature""");
}
@DataProvider
@@ -230,17 +227,17 @@ public class QGChangeEmailTemplateTest {
public void shouldFormatNewAlertWithThresholdProperlyFormatted(String alertText, String expectedFormattedAlertText) {
Notification notification = createNotification("Failed", alertText, "ERROR", "true");
- EmailMessage message = template.format(notification);
- assertThat(message.getMessageId(), is("alerts/45"));
- assertThat(message.getSubject(), is("New quality gate threshold reached on \"Foo\""));
- assertThat(message.getMessage(), is("" +
- "Project: Foo\n" +
- "Version: V1-SNAP\n" +
- "Quality gate status: Failed\n" +
- "\n" +
- "New quality gate threshold: " + expectedFormattedAlertText + "\n" +
- "\n" +
- "More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo"));
+ EmailMessage message = underTest.format(notification);
+ assertThat(message.getMessageId()).isEqualTo("alerts/45");
+ assertThat(message.getSubject()).isEqualTo("New quality gate threshold reached on \"Foo\"");
+ assertThat(message.getMessage()).isEqualTo("""
+ Project: Foo
+ Version: V1-SNAP
+ Quality gate status: Failed
+
+ New quality gate threshold: %s
+
+ More details at: http://nemo.sonarsource.org/dashboard?id=org.sonar.foo:foo""".formatted(expectedFormattedAlertText));
}