diff --git a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java
index e77cd2795..c3acb475b 100644
--- a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java
@@ -84,19 +84,22 @@ public class RecoverEmailCommand extends PlayerCommand {
private void createAndSendRecoveryCode(Player player, String email) {
String recoveryCode = recoveryCodeService.generateCode(player.getName());
- sendMailSsl.sendRecoveryCode(player.getName(), email, recoveryCode);
- commonService.send(player, MessageKey.RECOVERY_CODE_SENT);
+ boolean couldSendMail = sendMailSsl.sendRecoveryCode(player.getName(), email, recoveryCode);
+ if (couldSendMail) {
+ commonService.send(player, MessageKey.RECOVERY_CODE_SENT);
+ } else {
+ commonService.send(player, MessageKey.EMAIL_SEND_FAILURE);
+ }
}
private void processRecoveryCode(Player player, String code, String email) {
final String name = player.getName();
- if (!recoveryCodeService.isCodeValid(name, code)) {
+ if (recoveryCodeService.isCodeValid(name, code)) {
+ generateAndSendNewPassword(player, email);
+ recoveryCodeService.removeCode(name);
+ } else {
commonService.send(player, MessageKey.INCORRECT_RECOVERY_CODE);
- return;
}
-
- generateAndSendNewPassword(player, email);
- recoveryCodeService.removeCode(name);
}
private void generateAndSendNewPassword(Player player, String email) {
@@ -105,7 +108,11 @@ public class RecoverEmailCommand extends PlayerCommand {
HashedPassword hashNew = passwordSecurity.computeHash(thePass, name);
dataSource.updatePassword(name, hashNew);
- sendMailSsl.sendPasswordMail(name, email, thePass);
- commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
+ boolean couldSendMail = sendMailSsl.sendPasswordMail(name, email, thePass);
+ if (couldSendMail) {
+ commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
+ } else {
+ commonService.send(player, MessageKey.EMAIL_SEND_FAILURE);
+ }
}
}
diff --git a/src/main/java/fr/xephi/authme/mail/SendMailSSL.java b/src/main/java/fr/xephi/authme/mail/SendMailSSL.java
index 2076c1d19..c90d9422b 100644
--- a/src/main/java/fr/xephi/authme/mail/SendMailSSL.java
+++ b/src/main/java/fr/xephi/authme/mail/SendMailSSL.java
@@ -1,8 +1,8 @@
package fr.xephi.authme.mail;
-import fr.xephi.authme.AuthMe;
+import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger;
-import fr.xephi.authme.service.BukkitService;
+import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
@@ -11,6 +11,7 @@ import fr.xephi.authme.util.StringUtils;
import org.apache.commons.mail.EmailConstants;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
+import org.bukkit.Server;
import javax.activation.CommandMap;
import javax.activation.DataSource;
@@ -29,18 +30,19 @@ import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
/**
- * @author Xephi59
+ * Sends emails to players on behalf of the server.
*/
public class SendMailSSL {
- @Inject
- private AuthMe plugin;
- @Inject
- private Settings settings;
- @Inject
- private BukkitService bukkitService;
+ private final File dataFolder;
+ private final String serverName;
+ private final Settings settings;
- SendMailSSL() {
+ @Inject
+ SendMailSSL(@DataFolder File dataFolder, Server server, Settings settings) {
+ this.dataFolder = dataFolder;
+ this.serverName = server.getServerName();
+ this.settings = settings;
}
/**
@@ -59,62 +61,57 @@ public class SendMailSSL {
* @param name the name of the player
* @param mailAddress the player's email
* @param newPass the new password
+ * @return true if email could be sent, false otherwise
*/
- public void sendPasswordMail(String name, String mailAddress, String newPass) {
+ public boolean sendPasswordMail(String name, String mailAddress, String newPass) {
if (!hasAllInformation()) {
ConsoleLogger.warning("Cannot perform email registration: not all email settings are complete");
- return;
+ return false;
}
- final String mailText = replaceTagsForPasswordMail(settings.getPasswordEmailMessage(), name, newPass);
- bukkitService.runTaskAsynchronously(new Runnable() {
+ HtmlEmail email;
+ try {
+ email = initializeMail(mailAddress);
+ } catch (EmailException e) {
+ ConsoleLogger.logException("Failed to create email with the given settings:", e);
+ return false;
+ }
- @Override
- public void run() {
- HtmlEmail email;
- try {
- email = initializeMail(mailAddress);
- } catch (EmailException e) {
- ConsoleLogger.logException("Failed to create email with the given settings:", e);
- return;
- }
-
- String content = mailText;
- // Generate an image?
- File file = null;
- if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
- try {
- file = generateImage(name, plugin, newPass);
- content = embedImageIntoEmailContent(file, email, content);
- } catch (IOException | EmailException e) {
- ConsoleLogger.logException(
- "Unable to send new password as image for email " + mailAddress + ":", e);
- }
- }
-
- sendEmail(content, email);
- FileUtils.delete(file);
+ String mailText = replaceTagsForPasswordMail(settings.getPasswordEmailMessage(), name, newPass);
+ // Generate an image?
+ File file = null;
+ if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
+ try {
+ file = generateImage(name, newPass);
+ mailText = embedImageIntoEmailContent(file, email, mailText);
+ } catch (IOException | EmailException e) {
+ ConsoleLogger.logException(
+ "Unable to send new password as image for email " + mailAddress + ":", e);
}
- });
+ }
+
+ boolean couldSendEmail = sendEmail(mailText, email);
+ FileUtils.delete(file);
+ return couldSendEmail;
}
- public void sendRecoveryCode(String name, String email, String code) {
- String message = replaceTagsForRecoveryCodeMail(settings.getRecoveryCodeEmailMessage(),
- name, code, settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID));
-
+ public boolean sendRecoveryCode(String name, String email, String code) {
HtmlEmail htmlEmail;
try {
htmlEmail = initializeMail(email);
} catch (EmailException e) {
ConsoleLogger.logException("Failed to create email for recovery code:", e);
- return;
+ return false;
}
- sendEmail(message, htmlEmail);
+
+ String message = replaceTagsForRecoveryCodeMail(settings.getRecoveryCodeEmailMessage(),
+ name, code, settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID));
+ return sendEmail(message, htmlEmail);
}
- private static File generateImage(String name, AuthMe plugin, String newPass) throws IOException {
+ private File generateImage(String name, String newPass) throws IOException {
ImageGenerator gen = new ImageGenerator(newPass);
- File file = new File(plugin.getDataFolder(), name + "_new_pass.jpg");
+ File file = new File(dataFolder, name + "_new_pass.jpg");
ImageIO.write(gen.generateImage(), "jpg", file);
return file;
}
@@ -126,7 +123,8 @@ public class SendMailSSL {
return content.replace("", "");
}
- private HtmlEmail initializeMail(String emailAddress) throws EmailException {
+ @VisibleForTesting
+ HtmlEmail initializeMail(String emailAddress) throws EmailException {
String senderMail = settings.getProperty(EmailSettings.MAIL_ACCOUNT);
String senderName = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_SENDER_NAME))
? senderMail
@@ -147,7 +145,8 @@ public class SendMailSSL {
return email;
}
- private static boolean sendEmail(String content, HtmlEmail email) {
+ @VisibleForTesting
+ boolean sendEmail(String content, HtmlEmail email) {
Thread.currentThread().setContextClassLoader(SendMailSSL.class.getClassLoader());
// Issue #999: Prevent UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative
// cf. http://stackoverflow.com/questions/21856211/unsupporteddatatypeexception-no-object-dch-for-mime-type
@@ -177,14 +176,14 @@ public class SendMailSSL {
private String replaceTagsForPasswordMail(String mailText, String name, String newPass) {
return mailText
.replace("", name)
- .replace("", plugin.getServer().getServerName())
+ .replace("", serverName)
.replace("", newPass);
}
private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid) {
return mailText
.replace("", name)
- .replace("", plugin.getServer().getServerName())
+ .replace("", serverName)
.replace("", code)
.replace("", String.valueOf(hoursValid));
}
diff --git a/src/main/java/fr/xephi/authme/message/MessageFileHandler.java b/src/main/java/fr/xephi/authme/message/MessageFileHandler.java
index e870bdf36..a0d4e947c 100644
--- a/src/main/java/fr/xephi/authme/message/MessageFileHandler.java
+++ b/src/main/java/fr/xephi/authme/message/MessageFileHandler.java
@@ -53,7 +53,7 @@ public class MessageFileHandler {
if (message == null) {
ConsoleLogger.warning("Error getting message with key '" + key + "'. "
- + "Please verify your config file at '" + filename + "'");
+ + "Please update your config file '" + filename + "' (or run /authme messages)");
return getDefault(key);
}
return message;
diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/src/main/java/fr/xephi/authme/message/MessageKey.java
index ed3df4b37..f4bbd2fe0 100644
--- a/src/main/java/fr/xephi/authme/message/MessageKey.java
+++ b/src/main/java/fr/xephi/authme/message/MessageKey.java
@@ -153,6 +153,8 @@ public enum MessageKey {
INCOMPLETE_EMAIL_SETTINGS("incomplete_email_settings"),
+ EMAIL_SEND_FAILURE("email_send_failure"),
+
RECOVERY_CODE_SENT("recovery_code_sent"),
INCORRECT_RECOVERY_CODE("recovery_code_incorrect");
diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java
index 40e6806ce..02ef0ce14 100644
--- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java
+++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java
@@ -148,8 +148,12 @@ public class AsyncRegister implements AsynchronousProcess {
}
database.updateEmail(auth);
database.updateSession(auth);
- sendMailSsl.sendPasswordMail(name, email, password);
- syncProcessManager.processSyncEmailRegister(player);
+ boolean couldSendMail = sendMailSsl.sendPasswordMail(name, email, password);
+ if (couldSendMail) {
+ syncProcessManager.processSyncEmailRegister(player);
+ } else {
+ service.send(player, MessageKey.EMAIL_SEND_FAILURE);
+ }
}
private void passwordRegister(final Player player, String password, boolean autoLogin) {
diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml
index 0463d17ca..d04e38cd1 100644
--- a/src/main/resources/messages/messages_en.yml
+++ b/src/main/resources/messages/messages_en.yml
@@ -72,5 +72,6 @@ accounts_owned_self: 'You own %count accounts:'
accounts_owned_other: 'The player %name has %count accounts:'
kicked_admin_registered: 'An admin just registered you; please log in again'
incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.'
+email_send_failure: 'The email could not be sent. Please contact an administrator.'
recovery_code_sent: 'A recovery code to reset your password has been sent to your email.'
recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one'
diff --git a/src/main/resources/messages/messages_ro.yml b/src/main/resources/messages/messages_ro.yml
index f6233c76b..c872fe287 100644
--- a/src/main/resources/messages/messages_ro.yml
+++ b/src/main/resources/messages/messages_ro.yml
@@ -38,8 +38,8 @@ name_len: '&4Numele tau este prea scurt pentru a te inregistra!'
regex: '&4Numele tau contine caractere ilegale. Caractere permise: REG_EX'
add_email: '&3Te rugam adaugati email-ul la contul tau folosind comanda "/email add "'
recovery_email: '&3Ti-ai uitat parola? Te rugam foloseste comanda "/email recovery "'
-usage_captcha: '&3Pentru a te autentifica trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "'
-wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha "!'
+usage_captcha: '&3Pentru a te autentifica trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "'
+wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha THE_CAPTCHA"!'
valid_captcha: '&2Cod-ul captcha a fost scris corect!'
kick_forvip: '&3Un V.I.P a intrat pe server cand era plin!'
kick_fullserver: '&4Server-ul este plin, te rugam incearca din nou mai tarziu!'
diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
index 6d11412d8..978a2bef9 100644
--- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
+++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java
@@ -168,6 +168,7 @@ public class RecoverEmailCommandTest {
Player sender = mock(Player.class);
given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true);
+ given(sendMailSsl.sendRecoveryCode(anyString(), anyString(), anyString())).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false);
String email = "v@example.com";
given(dataSource.getAuth(name)).willReturn(newAuthWithEmail(email));
@@ -217,6 +218,7 @@ public class RecoverEmailCommandTest {
Player sender = mock(Player.class);
given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true);
+ given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false);
String email = "vulture@example.com";
String code = "A6EF3AC8";
@@ -251,6 +253,7 @@ public class RecoverEmailCommandTest {
Player sender = mock(Player.class);
given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true);
+ given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false);
String email = "shark@example.org";
PlayerAuth auth = newAuthWithEmail(email);
diff --git a/src/test/java/fr/xephi/authme/mail/SendMailSSLTest.java b/src/test/java/fr/xephi/authme/mail/SendMailSSLTest.java
new file mode 100644
index 000000000..7d3746ea6
--- /dev/null
+++ b/src/test/java/fr/xephi/authme/mail/SendMailSSLTest.java
@@ -0,0 +1,248 @@
+package fr.xephi.authme.mail;
+
+import ch.jalu.injector.testing.BeforeInjecting;
+import ch.jalu.injector.testing.DelayedInjectionRunner;
+import ch.jalu.injector.testing.InjectDelayed;
+import fr.xephi.authme.TestHelper;
+import fr.xephi.authme.initialization.DataFolder;
+import fr.xephi.authme.settings.Settings;
+import fr.xephi.authme.settings.properties.EmailSettings;
+import fr.xephi.authme.settings.properties.SecuritySettings;
+import org.apache.commons.mail.EmailException;
+import org.apache.commons.mail.HtmlEmail;
+import org.bukkit.Server;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Test for {@link SendMailSSL}.
+ */
+@RunWith(DelayedInjectionRunner.class)
+public class SendMailSSLTest {
+
+ @InjectDelayed
+ private SendMailSSL sendMailSSL;
+
+ @Mock
+ private Settings settings;
+ @Mock
+ private Server server;
+ @DataFolder
+ private File dataFolder;
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @BeforeClass
+ public static void initLogger() {
+ TestHelper.setupLogger();
+ }
+
+ @BeforeInjecting
+ public void initFields() throws IOException {
+ dataFolder = temporaryFolder.newFolder();
+ given(server.getServerName()).willReturn("serverName");
+ given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("mail@example.org");
+ given(settings.getProperty(EmailSettings.MAIL_PASSWORD)).willReturn("pass1234");
+ }
+
+ @Test
+ public void shouldHaveAllInformation() {
+ // given / when / then
+ assertThat(sendMailSSL.hasAllInformation(), equalTo(true));
+ }
+
+ @Test
+ public void shouldSendPasswordMail() throws EmailException {
+ // given
+ given(settings.getPasswordEmailMessage())
+ .willReturn("Hi , your new password for is ");
+ given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false);
+ SendMailSSL sendMailSpy = spy(sendMailSSL);
+ HtmlEmail email = mock(HtmlEmail.class);
+ doReturn(email).when(sendMailSpy).initializeMail(anyString());
+ doReturn(true).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
+
+ // when
+ boolean result = sendMailSpy.sendPasswordMail("Player", "user@example.com", "new_password");
+
+ // then
+ assertThat(result, equalTo(true));
+ verify(sendMailSpy).initializeMail("user@example.com");
+ ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class);
+ verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
+ assertThat(messageCaptor.getValue(),
+ equalTo("Hi Player, your new password for serverName is new_password"));
+ }
+
+ @Test
+ public void shouldHandleMailCreationError() throws EmailException {
+ // given
+ SendMailSSL sendMailSpy = spy(sendMailSSL);
+ doThrow(EmailException.class).when(sendMailSpy).initializeMail(anyString());
+
+ // when
+ boolean result = sendMailSpy.sendPasswordMail("Player", "user@example.com", "new_password");
+
+ // then
+ assertThat(result, equalTo(false));
+ verify(sendMailSpy).initializeMail("user@example.com");
+ verify(sendMailSpy, never()).sendEmail(anyString(), any(HtmlEmail.class));
+ }
+
+ @Test
+ public void shouldHandleMailSendingFailure() throws EmailException {
+ // given
+ given(settings.getPasswordEmailMessage()).willReturn("Hi , your new pass is ");
+ given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false);
+ SendMailSSL sendMailSpy = spy(sendMailSSL);
+ HtmlEmail email = mock(HtmlEmail.class);
+ doReturn(email).when(sendMailSpy).initializeMail(anyString());
+ doReturn(false).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
+
+ // when
+ boolean result = sendMailSpy.sendPasswordMail("bobby", "user@example.com", "myPassw0rd");
+
+ // then
+ assertThat(result, equalTo(false));
+ verify(sendMailSpy).initializeMail("user@example.com");
+ ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class);
+ verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
+ assertThat(messageCaptor.getValue(), equalTo("Hi bobby, your new pass is myPassw0rd"));
+ }
+
+ @Test
+ public void shouldSendRecoveryCode() throws EmailException {
+ // given
+ given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7);
+ given(settings.getRecoveryCodeEmailMessage())
+ .willReturn("Hi , your code on is (valid hours)");
+ SendMailSSL sendMailSpy = spy(sendMailSSL);
+ HtmlEmail email = mock(HtmlEmail.class);
+ doReturn(email).when(sendMailSpy).initializeMail(anyString());
+ doReturn(true).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
+
+ // when
+ boolean result = sendMailSpy.sendRecoveryCode("Timmy", "tim@example.com", "12C56A");
+
+ // then
+ assertThat(result, equalTo(true));
+ verify(sendMailSpy).initializeMail("tim@example.com");
+ ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class);
+ verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
+ assertThat(messageCaptor.getValue(), equalTo("Hi Timmy, your code on serverName is 12C56A (valid 7 hours)"));
+ }
+
+ @Test
+ public void shouldHandleMailCreationErrorForRecoveryCode() throws EmailException {
+ // given
+ SendMailSSL sendMailSpy = spy(sendMailSSL);
+ doThrow(EmailException.class).when(sendMailSpy).initializeMail(anyString());
+
+ // when
+ boolean result = sendMailSpy.sendRecoveryCode("Player", "player@example.org", "ABC1234");
+
+ // then
+ assertThat(result, equalTo(false));
+ verify(sendMailSpy).initializeMail("player@example.org");
+ verify(sendMailSpy, never()).sendEmail(anyString(), any(HtmlEmail.class));
+ }
+
+ @Test
+ public void shouldHandleFailureToSendRecoveryCode() throws EmailException {
+ // given
+ given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7);
+ given(settings.getRecoveryCodeEmailMessage()).willReturn("Hi , your code is ");
+ SendMailSSL sendMailSpy = spy(sendMailSSL);
+ HtmlEmail email = mock(HtmlEmail.class);
+ doReturn(email).when(sendMailSpy).initializeMail(anyString());
+ doReturn(false).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
+
+ // when
+ boolean result = sendMailSpy.sendRecoveryCode("John", "user@example.com", "1DEF77");
+
+ // then
+ assertThat(result, equalTo(false));
+ verify(sendMailSpy).initializeMail("user@example.com");
+ ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class);
+ verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
+ assertThat(messageCaptor.getValue(), equalTo("Hi John, your code is 1DEF77"));
+ }
+
+ @Test
+ public void shouldCreateEmailObject() throws EmailException {
+ // given
+ given(settings.getProperty(EmailSettings.SMTP_PORT)).willReturn(465);
+ String smtpHost = "mail.example.com";
+ given(settings.getProperty(EmailSettings.SMTP_HOST)).willReturn(smtpHost);
+ String senderMail = "sender@example.org";
+ given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn(senderMail);
+ String senderName = "Server administration";
+ given(settings.getProperty(EmailSettings.MAIL_SENDER_NAME)).willReturn(senderName);
+
+ // when
+ HtmlEmail email = sendMailSSL.initializeMail("recipient@example.com");
+
+ // then
+ assertThat(email, not(nullValue()));
+ assertThat(email.getToAddresses(), hasSize(1));
+ assertThat(email.getToAddresses().get(0).getAddress(), equalTo("recipient@example.com"));
+ assertThat(email.getFromAddress().getAddress(), equalTo(senderMail));
+ assertThat(email.getFromAddress().getPersonal(), equalTo(senderName));
+ assertThat(email.getHostName(), equalTo(smtpHost));
+ assertThat(email.getSmtpPort(), equalTo("465"));
+ }
+
+ @Test
+ public void shouldCreateEmailObjectWithOAuth2() throws EmailException {
+ // given
+ given(settings.getProperty(EmailSettings.SMTP_PORT)).willReturn(587);
+ given(settings.getProperty(EmailSettings.OAUTH2_TOKEN)).willReturn("oAuth2 token");
+ String smtpHost = "mail.example.com";
+ given(settings.getProperty(EmailSettings.SMTP_HOST)).willReturn(smtpHost);
+ String senderMail = "sender@example.org";
+ given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn(senderMail);
+
+ // when
+ HtmlEmail email = sendMailSSL.initializeMail("recipient@example.com");
+
+ // then
+ assertThat(email, not(nullValue()));
+ assertThat(email.getToAddresses(), hasSize(1));
+ assertThat(email.getToAddresses().get(0).getAddress(), equalTo("recipient@example.com"));
+ assertThat(email.getFromAddress().getAddress(), equalTo(senderMail));
+ assertThat(email.getHostName(), equalTo(smtpHost));
+ assertThat(email.getSmtpPort(), equalTo("587"));
+
+ Properties mailProperties = email.getMailSession().getProperties();
+ assertThat(mailProperties.getProperty("mail.smtp.auth.mechanisms"), equalTo("XOAUTH2"));
+ assertThat(mailProperties.getProperty("mail.smtp.auth.plain.disable"), equalTo("true"));
+ assertThat(mailProperties.getProperty(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP), equalTo("oAuth2 token"));
+ }
+
+}