package uk.ac.ox.zoo.seeg.abraid.mp.common.service.core; import org.apache.commons.io.FileUtils; import org.apache.commons.mail.DefaultAuthenticator; import org.apache.commons.mail.Email; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentCaptor; import uk.ac.ox.zoo.seeg.abraid.mp.common.config.SmtpConfiguration; import uk.ac.ox.zoo.seeg.abraid.mp.common.util.EmailFactory; import javax.mail.PasswordAuthentication; import java.io.File; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Future; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; import static uk.ac.ox.zoo.seeg.abraid.mp.testutils.GeneralTestUtils.captorForClass; /** * Tests for EmailServiceImpl. * Copyright (c) 2014 University of Oxford */ public class EmailServiceTest { @Rule public TemporaryFolder testFolder = new TemporaryFolder(); ///CHECKSTYLE:SUPPRESS VisibilityModifier @Test public void sendEmailCorrectlySetsUpSMTP() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "", "", expectation, new Class[0], new File[0]); // Act target.sendEmail("", "", ""); // Assert verify(email).setHostName(expectation.getAddress()); verify(email).setSmtpPort(expectation.getPort()); verify(email).setSslSmtpPort("" + expectation.getPort()); verify(email).setStartTLSRequired(expectation.useSSL()); ArgumentCaptor<DefaultAuthenticator> captor = captorForClass(DefaultAuthenticator.class); verify(email).setAuthenticator(captor.capture()); DefaultAuthenticator authenticator = captor.getValue(); Field protectedField = DefaultAuthenticator.class.getDeclaredField("authentication"); protectedField.setAccessible(true); PasswordAuthentication authentication = (PasswordAuthentication) protectedField.get(authenticator); assertThat(authentication.getUserName()).isEqualTo(expectation.getUsername()); assertThat(authentication.getPassword()).isEqualTo(expectation.getPassword()); } @Test public void sendEmailCorrectlySetFields() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[0]); // Act target.sendEmail("ToAddress", "Subject", "Body"); // Assert verify(email).addTo("ToAddress"); verify(email).setFrom("FromAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); } @Test public void sendEmailSendsMessage() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[0]); // Act target.sendEmail("ToAddress", "Subject", "Body"); // Assert verify(email).send(); } private EmailFactory arrangeEmailFactory(Email email) { EmailFactory factory = mock(EmailFactory.class); if (email != null) { when(factory.createEmail()).thenReturn(email); } else { when(factory.createEmail()).thenReturn(mock(Email.class)); } return factory; } private SmtpConfiguration arrangeSMTP() { SmtpConfiguration smtp = mock(SmtpConfiguration.class); when(smtp.getAddress()).thenReturn("abc"); when(smtp.getPort()).thenReturn(54321); when(smtp.useSSL()).thenReturn(true); when(smtp.getUsername()).thenReturn("cab"); when(smtp.getPassword()).thenReturn("cba"); return smtp; } @Test public void sendEmailCanGenerateMessageFromTemplate() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); FileUtils.writeStringToFile(new File(testFolder.getRoot().toString(), "template.ftl"), "expected result"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[] {testFolder.getRoot()}); // Act target.sendEmail("", "", "template.ftl", null); // Assert verify(email).setMsg("expected result"); verify(email).send(); } @Test public void sendEmailFindsCorrectTemplate() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); File dir1 = testFolder.newFolder(); File dir2 = testFolder.newFolder(); FileUtils.writeStringToFile(new File(dir1.toString(), "template"), "unexpected result"); FileUtils.writeStringToFile(new File(dir2.toString(), "templat.ftl"), "unexpected result"); FileUtils.writeStringToFile(new File(dir2.toString(), "template.ftl"), "expected result"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[] {dir1, dir2}); // Act target.sendEmail("", "", "template.ftl", null); // Assert verify(email).setMsg("expected result"); } @Test public void sendEmailGivesCorrectTemplatePrecedence() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); File dir1 = testFolder.newFolder(); File dir2 = testFolder.newFolder(); FileUtils.writeStringToFile(new File(dir1.toString(), "template.ftl"), "expected result"); FileUtils.writeStringToFile(new File(dir2.toString(), "template.ftl"), "unexpected result"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[] {dir1, dir2}); // Act target.sendEmail("", "", "template.ftl", null); // Assert verify(email).setMsg("expected result"); } @Test public void sendEmailAppliesTemplateToDataCorrectly() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); FileUtils.writeStringToFile(new File(testFolder.getRoot().toString(), "template.ftl"), "expected result${foo}"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[] {testFolder.getRoot()}); Map<String, Object> data = new HashMap<>(); data.put("foo", "!"); // Act target.sendEmail("", "", "template.ftl", data); // Assert verify(email).setMsg("expected result!"); } @Test public void sendEmailSendsCorrectMessage() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[0]); // Act target.sendEmail("ToAddress", "Subject", "Body"); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } @Test public void sendEmailSendsCorrectTemplatedMessage() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); FileUtils.writeStringToFile(new File(testFolder.getRoot().toString(), "template.ftl"), "Body"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[] {testFolder.getRoot()}); // Act target.sendEmail("ToAddress", "Subject", "template.ftl", new HashMap<String, Object>()); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } @Test public void sendEmailInBackgroundSendsCorrectMessage() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[0]); // Act Future result = target.sendEmailInBackground("ToAddress", "Subject", "Body"); result.get(); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } @Test public void sendEmailInBackgroundSendsCorrectTemplatedMessage() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); FileUtils.writeStringToFile(new File(testFolder.getRoot().toString(), "template.ftl"), "Body"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "", expectation, new Class[0], new File[] {testFolder.getRoot()}); // Act Future result = target.sendEmailInBackground("ToAddress", "Subject", "template.ftl", new HashMap<String, Object>()); result.get(); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } @Test public void sendEmailSendsCorrectMessageWithDefaultToAddress() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "ToAddress", expectation, new Class[0], new File[0]); // Act target.sendEmail("Subject", "Body"); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } @Test public void sendEmailSendsCorrectTemplatedMessageWithDefaultToAddress() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); FileUtils.writeStringToFile(new File(testFolder.getRoot().toString(), "template.ftl"), "Body"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "ToAddress", expectation, new Class[0], new File[] {testFolder.getRoot()}); // Act target.sendEmail("Subject", "template.ftl", new HashMap<String, Object>()); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } @Test public void sendEmailInBackgroundSendsCorrectMessageWithDefaultToAddress() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "ToAddress", expectation, new Class[0], new File[0]); // Act Future result = target.sendEmailInBackground("Subject", "Body"); result.get(); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } @Test public void sendEmailInBackgroundSendsCorrectTemplatedMessageWithDefaultToAddress() throws Exception { // Arrange SmtpConfiguration expectation = arrangeSMTP(); Email email = mock(Email.class); FileUtils.writeStringToFile(new File(testFolder.getRoot().toString(), "template.ftl"), "Body"); EmailServiceImpl target = new EmailServiceImpl(arrangeEmailFactory(email), "FromAddress", "ToAddress", expectation, new Class[0], new File[] {testFolder.getRoot()}); // Act Future result = target.sendEmailInBackground("Subject", "template.ftl", new HashMap<String, Object>()); result.get(); // Assert verify(email).addTo("ToAddress"); verify(email).setSubject("Subject"); verify(email).setMsg("Body"); verify(email).send(); } }