1
2
3
4
5
6
7
8
9
10
11 package test.atlassian.mail.server;
12
13 import com.atlassian.mail.Email;
14 import com.atlassian.mail.MailException;
15 import com.atlassian.mail.MailUtils;
16 import com.atlassian.mail.server.SMTPMailServer;
17 import com.atlassian.mail.server.impl.SMTPMailServerImpl;
18 import com.sun.mail.util.PropUtil;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.ArgumentCaptor;
23 import org.powermock.api.mockito.PowerMockito;
24 import org.powermock.core.classloader.annotations.PrepareForTest;
25 import org.powermock.modules.junit4.PowerMockRunner;
26 import test.mock.mail.server.MockSMTPMailServer;
27
28 import javax.mail.Address;
29 import javax.mail.Message;
30 import javax.mail.MessagingException;
31 import javax.mail.Multipart;
32 import javax.mail.NoSuchProviderException;
33 import javax.mail.Session;
34 import javax.mail.Transport;
35 import javax.mail.URLName;
36 import javax.mail.internet.AddressException;
37 import javax.mail.internet.InternetAddress;
38 import javax.mail.internet.MimeBodyPart;
39 import javax.mail.internet.MimeMessage;
40 import javax.mail.internet.MimeMultipart;
41 import javax.naming.NamingException;
42
43 import java.io.IOException;
44 import java.util.Properties;
45
46 import static org.junit.Assert.assertArrayEquals;
47 import static org.junit.Assert.assertEquals;
48 import static org.junit.Assert.assertFalse;
49 import static org.junit.Assert.assertNotNull;
50 import static org.junit.Assert.assertTrue;
51 import static org.junit.Assert.fail;
52 import static org.mockito.AdditionalMatchers.aryEq;
53 import static org.mockito.Matchers.eq;
54 import static org.mockito.Mockito.mock;
55 import static org.mockito.Mockito.verify;
56 import static org.mockito.Mockito.when;
57
58
59
60
61
62
63
64
65 @RunWith(PowerMockRunner.class)
66 @PrepareForTest({Session.class, PropUtil.class})
67 public class TestSMTPMailServer
68 {
69
70 private Session mockSession;
71 private Transport mockTransport;
72
73
74 @Before
75 public void setupMockSessionAndTransport() throws NoSuchProviderException {
76 mockSession = PowerMockito.mock(Session.class);
77 PowerMockito.mockStatic(PropUtil.class);
78 when(PropUtil.getBooleanSessionProperty(mockSession, "mail.mime.address.strict", true)).thenReturn(false);
79 mockTransport = mock(Transport.class);
80 when(mockSession.getTransport("smtp")).thenReturn(mockTransport);
81 }
82
83 @Test
84 public void testConstructor()
85 {
86 SMTPMailServer sms = new SMTPMailServerImpl(new Long(1), "name", "desc", "owen@atlassian.com", "[OWEN]", false, "mail.atlassian.com", "ofellows", "owen01");
87 assertEquals("Expected from","owen@atlassian.com", sms.getDefaultFrom());
88 assertEquals("Expected prefix", "[OWEN]", sms.getPrefix());
89 assertFalse("Expected the mail server not to be a session server", sms.isSessionServer());
90 }
91
92
93 @Test
94 public void testGetsSets()
95 {
96 SMTPMailServer sms = new SMTPMailServerImpl(new Long(1), "name", "desc", "", "", false, "mail.atlassian.com", "ofellows", "owen01");
97 sms.setDefaultFrom("owen@atlassian.com");
98 assertEquals("Expected default from to be owen@atlassian.com","owen@atlassian.com", sms.getDefaultFrom());
99 sms.setPrefix("[OWEN]");
100 assertEquals("Expected prefix to be [OWEN]", "[OWEN]", sms.getPrefix());
101 sms.setSessionServer(true);
102 assertTrue(sms.isSessionServer());
103 }
104
105 @Test
106 public void testGetSessionNoUser() throws NamingException, MailException
107 {
108 SMTPMailServer sms = new SMTPMailServerImpl(new Long(1), "name", "desc", "owen@atlassian.com", "[OWEN]", false, "mail.atlassian.com", null, null);
109 assertNotNull(sms.getSession());
110 }
111
112 @Test
113 public void testGetSessionWithUser() throws NamingException, MailException
114 {
115
116
117
118
119 SMTPMailServer sms = new SMTPMailServerImpl(new Long(1), "name", "desc", "owen@atlassian.com", "[OWEN]", false, "mail.atlassian.com", "ofellows", "owen01");
120 Session session = sms.getSession();
121 assertNotNull(session);
122 assertEquals("ofellows", session.getPasswordAuthentication(new URLName("smtp", "mail.atlassian.com", 25, null, null, null)).getUserName());
123 assertEquals("owen01", session.getPasswordAuthentication(new URLName("smtp", "mail.atlassian.com", 25, null, null, null)).getPassword());
124 }
125
126 @Test
127 public void testSend() throws NamingException, MessagingException, AddressException, MailException, IOException {
128
129 MimeMessage expectedMessage = setupExpectedMessage("owen@atlassian.com", "scott@atlassian.com", "mike@atlassian.con", "james@atlassian.com", "[OWEN] Test Subject", "Test Body", "text/plain");
130
131 SMTPMailServer mockSmtpMailServer = new MockSMTPMailServer(new Long(1), "name", "desc", "owen@atlassian.com", "[OWEN]", false, "mail.atlassian.com", "ofellows", "owen01", mockSession);
132 Address[] expectedDestinations = new Address[] {new InternetAddress("scott@atlassian.com"), new InternetAddress("mike@atlassian.com"), new InternetAddress("james@atlassian.com")};
133
134 Email email = new Email("scott@atlassian.com").setSubject("Test Subject").setBody("Test Body").setBcc("james@atlassian.com").setCc("mike@atlassian.com").setFrom("owen@atlassian.com");
135 mockSmtpMailServer.send(email);
136 verifySentMessage(mockTransport, expectedMessage, expectedDestinations);
137 }
138
139
140 @Test
141 public void testSendWithAttachment() throws NamingException, MessagingException, AddressException, MailException, IOException
142 {
143 SMTPMailServer mockSmtpMailServer = new MockSMTPMailServer(new Long(1), "name", "desc", "owen@atlassian.com", "[OWEN]", false, "mail.atlassian.com", "ofellows", "owen01", mockSession);
144
145 Multipart multipart = new MimeMultipart();
146
147 MimeBodyPart exportZip = MailUtils.createAttachmentMimeBodyPart("C:/export.zip");
148 MimeBodyPart logTxt = MailUtils.createAttachmentMimeBodyPart("C:/log.txt");
149 multipart.addBodyPart(exportZip);
150 multipart.addBodyPart(logTxt);
151
152
153 MimeBodyPart messageBodyPart = new MimeBodyPart();
154 messageBodyPart.setText("Test Body", "text/plain");
155
156 multipart.addBodyPart(messageBodyPart);
157
158 MimeMessage expectedMessage = setupExpectedMessage("owen@atlassian.com", "scott@atlassian.com", "mike@atlassian.com", null, "[OWEN] Test Subject", multipart, null);
159
160
161 multipart.removeBodyPart(messageBodyPart);
162
163 try
164 {
165 Email email = new Email("scott@atlassian.com").setCc("mike@atlassian.com").setSubject("Test Subject").setBody("Test Body").setFrom("owen@atlassian.com").setMultipart(multipart);
166 mockSmtpMailServer.send(email);
167 }
168 catch (Exception e)
169 {
170 fail();
171 }
172
173 verifySentMessage(mockTransport, expectedMessage, new InternetAddress[]{new InternetAddress("scott@atlassian.com"), new InternetAddress("mike@atlassian.com") });
174 }
175
176
177
178
179
180 @Test
181 public void testGetJNDIServer() throws NamingException, MailException
182 {
183 final javax.mail.Session sessionInstance = javax.mail.Session.getInstance(new Properties(), null);
184
185 SMTPMailServer sms = new SMTPMailServerImpl(new Long(1), "name", "desc", "owen@atlassian.com", "[OWEN]", true, "mail.atlassian.com", null, null)
186 {
187 protected Object getJndiSession() throws NamingException
188 {
189 return sessionInstance;
190 }
191 };
192
193 Session session = sms.getSession();
194 assertEquals(sessionInstance, session);
195
196 }
197
198
199
200
201
202 @Test
203 public void testIncorrectJndiClass() throws NamingException, MailException
204 {
205 SMTPMailServer sms = new SMTPMailServerImpl(new Long(1), "name", "desc", "owen@atlassian.com", "[OWEN]", true, "mail.atlassian.com", null, null)
206 {
207 protected Object getJndiSession() throws NamingException
208 {
209 return new Object();
210 }
211 };
212
213 try
214 {
215 sms.getSession();
216 fail("Expected IllegalArgumentException when wrong class type in jdni location");
217 }
218 catch (IllegalArgumentException e)
219 {
220
221 }
222 }
223
224
225
226
227
228 @Test
229 public void testSendFail() throws Exception
230 {
231 SMTPMailServer mailServer = new SMTPMailServerImpl(null, "default", "", "", "", false, "mail.atlassian.com", "", "");
232 try
233 {
234 Email email = new Email("mike@atlassian.com").setSubject("Test Subject").setBody("Test Body");
235 mailServer.send(email);
236 fail();
237 }
238 catch (MailException e)
239 {
240 assertEquals("Tried to send mail (Test Subject) from no one (no 'from' and 'default from' specified).", e.getMessage());
241 }
242 }
243
244 @Test
245 public void testSendMail1() throws Exception
246 {
247
248 SMTPMailServer mockSMTPMailServer = new MockSMTPMailServer(new Long(-1), "default", "", "owen@atlassian.com", "", false, "mail.atlassian.com", "", "", mockSession);
249
250 MimeMessage expectedMessage = setupExpectedMessage("owen@atlassian.com", "mike@altassian.com", null, null ,"Test Subject 1", "Test 1", "text/plain");
251
252 Email email = new Email("mike@atlassian.com").setSubject("Test Subject 1").setBody("Test 1").setFrom("owen@atlassian.com");
253 mockSMTPMailServer.send(email);
254
255 verifySentMessage(mockTransport, expectedMessage, new Address[] {new InternetAddress("mike@atlassian.com")});
256 }
257
258 @Test
259 public void testSendMail2() throws Exception
260 {
261 SMTPMailServer mockSMTPMailServer = new MockSMTPMailServer(new Long(-1), "default", "", "owen@atlassian.com", "", false, "mail.atlassian.com", "", "", mockSession);
262
263 MimeMessage expectedMessage = setupExpectedMessage("owen@atlassian.com", "mike@altassian.com", "scott@atlassian.con", null ,"Test Subject 2", "/testing/Test 2", "text/plain");
264
265 Email email = new Email("mike@atlassian.com").setSubject("Test Subject 2").setCc("scott@atlassian.com").setBody("/testing/Test 2").setFrom("owen@atlassian.com");
266 mockSMTPMailServer.send(email);
267
268 verifySentMessage(mockTransport, expectedMessage, new Address[] {new InternetAddress("mike@atlassian.com"), new InternetAddress("scott@atlassian.com")});
269 }
270
271 @Test
272 public void testSendMail3() throws Exception
273 {
274 SMTPMailServer mockSMTPMailServer = new MockSMTPMailServer(new Long(-1), "default", "", "owen@atlassian.com", "", false, "mail.atlassian.com", "", "", mockSession);
275
276 MimeMessage expectedMessage = setupExpectedMessage("owen@atlassian.com", "mike@altassian.com", null, null ,"Test Subject 3", "/testing/Test 3", "UTF-8");
277
278
279
280 Email email = new Email("mike@atlassian.com").setSubject("Test Subject 3").setBody("/testing/Test 3").setFrom("owen@atlassian.com");
281 mockSMTPMailServer.send(email);
282
283 verifySentMessage(mockTransport, expectedMessage, new Address[] {new InternetAddress("mike@atlassian.com")});
284 }
285
286 private void verifySentMessage(Transport mockTransport, MimeMessage expectedMessage, Address[] expectedDestinations) throws MessagingException, IOException
287 {
288 ArgumentCaptor<MimeMessage> capturedMessage = ArgumentCaptor.forClass(MimeMessage.class);
289 verify(mockTransport).sendMessage(capturedMessage.capture(), aryEq(expectedDestinations));
290 MimeMessage actualMessageSent = capturedMessage.getValue();
291 assertEquals("Subject should be set correctly", expectedMessage.getSubject(), actualMessageSent.getSubject());
292 assertEquals("The content must be the same", expectedMessage.getContent(), actualMessageSent.getContent());
293 assertArrayEquals("The sender must be the same", expectedMessage.getFrom(), actualMessageSent.getFrom());
294 }
295
296 private MimeMessage setupExpectedMessage(String fromAddress, String toAddress, String ccAddress, String bccAddress, String subject, Object body, String mimeType) throws MessagingException {
297 MimeMessage expectedMessage = new MimeMessage(mockSession);
298
299 expectedMessage.setFrom(new InternetAddress(fromAddress));
300 expectedMessage.setRecipients(Message.RecipientType.TO, toAddress);
301 if (ccAddress != null)
302 {
303 expectedMessage.setRecipients(Message.RecipientType.CC, ccAddress);
304 }
305 if (bccAddress != null)
306 {
307 expectedMessage.setRecipients(Message.RecipientType.BCC, bccAddress);
308 }
309 expectedMessage.setSubject(subject);
310 if (body instanceof Multipart)
311 {
312 expectedMessage.setContent((Multipart)body);
313 }
314 else
315 {
316 expectedMessage.setContent(body, mimeType);
317 }
318 return expectedMessage;
319 }
320
321 }