1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.mail;
18
19 import static org.easymock.EasyMock.expect;
20 import static org.hamcrest.CoreMatchers.containsString;
21 import static org.junit.Assert.*;
22 import static org.powermock.api.easymock.PowerMock.createMock;
23 import static org.powermock.api.easymock.PowerMock.replay;
24
25 import java.io.BufferedOutputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.File;
28 import java.io.IOException;
29 import java.net.URL;
30 import java.util.Date;
31 import java.util.Enumeration;
32 import java.util.List;
33
34 import javax.activation.DataHandler;
35 import javax.mail.Header;
36 import javax.mail.MessagingException;
37 import javax.mail.Multipart;
38 import javax.mail.internet.InternetAddress;
39 import javax.mail.internet.MimeMessage;
40
41 import org.apache.commons.mail.settings.EmailConfiguration;
42 import org.junit.After;
43 import org.junit.Before;
44 import org.subethamail.wiser.Wiser;
45 import org.subethamail.wiser.WiserMessage;
46
47
48
49
50
51
52 public abstract class AbstractEmailTest
53 {
54
55 public static final int BODY_END_PAD = 3;
56
57
58 public static final int BODY_START_PAD = 2;
59
60
61 private static final String LINE_SEPARATOR = "\r\n";
62
63
64 private static int mailServerPort = 2500;
65
66
67 protected Wiser fakeMailServer;
68
69
70 protected String strTestMailServer = "localhost";
71
72
73 protected String strTestMailFrom = "test_from@apache.org";
74
75
76 protected String strTestMailTo = "test_to@apache.org";
77
78
79 protected String strTestUser = "user";
80
81
82 protected String strTestPasswd = "password";
83
84
85 protected String strTestURL = EmailConfiguration.TEST_URL;
86
87
88 protected String[] testCharsValid =
89 {
90 " ",
91 "a",
92 "A",
93 "\uc5ec",
94 "0123456789",
95 "012345678901234567890"
96 };
97
98
99 protected String[] endOfLineCombinations =
100 {
101 "\n",
102 "\r",
103 "\r\n",
104 "\n\r",
105 };
106
107
108 protected String[] testCharsNotValid = {"", null};
109
110
111 private File emailOutputDir;
112
113
114 private static int fileNameCounter;
115
116 @Before
117 public void setUpAbstractEmailTest()
118 {
119 emailOutputDir = new File("target/test-emails");
120 if (!emailOutputDir.exists())
121 {
122 emailOutputDir.mkdirs();
123 }
124 }
125
126 @After
127 public void tearDownEmailTest()
128 {
129
130 if (this.fakeMailServer != null && !isMailServerStopped(fakeMailServer))
131 {
132 this.fakeMailServer.stop();
133 assertTrue("Mail server didn't stop", isMailServerStopped(fakeMailServer));
134 }
135
136 this.fakeMailServer = null;
137 }
138
139
140
141
142
143 protected int getMailServerPort()
144 {
145 return mailServerPort;
146 }
147
148
149
150
151
152
153
154
155 protected void saveEmailToFile(final WiserMessage email) throws IOException, MessagingException
156 {
157 final int currCounter = fileNameCounter++ % 10;
158 final String emailFileName = "email" + new Date().getTime() + "-" + currCounter + ".eml";
159 final File emailFile = new File(emailOutputDir, emailFileName);
160 EmailUtils.writeMimeMessage(emailFile, email.getMimeMessage() );
161 }
162
163
164
165
166
167 public String getMessageAsString(final int intMsgNo)
168 {
169 final List<?> receivedMessages = fakeMailServer.getMessages();
170 assertTrue("mail server didn't get enough messages", receivedMessages.size() >= intMsgNo);
171
172 final WiserMessage emailMessage = (WiserMessage) receivedMessages.get(intMsgNo);
173
174 if (emailMessage != null)
175 {
176 try
177 {
178 return serializeEmailMessage(emailMessage);
179 }
180 catch (final Exception e)
181 {
182
183 }
184 }
185 fail("Message not found");
186 return "";
187 }
188
189
190
191
192
193
194 public void getMailServer()
195 {
196 if (this.fakeMailServer == null || isMailServerStopped(fakeMailServer))
197 {
198 mailServerPort++;
199
200 this.fakeMailServer = new Wiser();
201 this.fakeMailServer.setPort(getMailServerPort());
202 this.fakeMailServer.start();
203
204 assertFalse("fake mail server didn't start", isMailServerStopped(fakeMailServer));
205
206 final Date dtStartWait = new Date();
207 while (isMailServerStopped(fakeMailServer))
208 {
209
210 if (this.fakeMailServer != null
211 && !isMailServerStopped(fakeMailServer))
212 {
213 break;
214 }
215
216
217 if (dtStartWait.getTime() + EmailConfiguration.TIME_OUT
218 <= new Date().getTime())
219 {
220 fail("Mail server failed to start");
221 }
222 }
223 }
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238 protected WiserMessage validateSend(
239 final Wiser mailServer,
240 final String strSubject,
241 final InternetAddress fromAdd,
242 final List<InternetAddress> toAdd,
243 final List<InternetAddress> ccAdd,
244 final List<InternetAddress> bccAdd,
245 final boolean boolSaveToFile)
246 throws IOException
247 {
248 assertTrue("mail server doesn't contain expected message",
249 mailServer.getMessages().size() == 1);
250 final WiserMessage emailMessage = mailServer.getMessages().get(0);
251
252 if (boolSaveToFile)
253 {
254 try
255 {
256 this.saveEmailToFile(emailMessage);
257 }
258 catch(final MessagingException me)
259 {
260 final IllegalStateException ise =
261 new IllegalStateException("caught MessagingException during saving the email");
262 ise.initCause(me);
263 throw ise;
264 }
265 }
266
267 try
268 {
269
270 final MimeMessage mimeMessage = emailMessage.getMimeMessage();
271
272
273 assertEquals("got wrong subject from mail",
274 strSubject, mimeMessage.getHeader("Subject", null));
275
276
277 assertEquals("got wrong From: address from mail",
278 fromAdd.toString(), mimeMessage.getHeader("From", null));
279
280
281 assertTrue("got wrong To: address from mail",
282 toAdd.toString().contains(mimeMessage.getHeader("To", null)));
283
284
285 if (ccAdd.size() > 0)
286 {
287 assertTrue("got wrong Cc: address from mail",
288 ccAdd.toString().contains(mimeMessage.getHeader("Cc", null)));
289 }
290
291
292 if (bccAdd.size() > 0)
293 {
294 assertTrue("got wrong Bcc: address from mail",
295 bccAdd.toString().contains(mimeMessage.getHeader("Bcc", null)));
296 }
297 }
298 catch (final MessagingException me)
299 {
300 final IllegalStateException ise =
301 new IllegalStateException("caught MessagingException in validateSend()");
302 ise.initCause(me);
303 throw ise;
304 }
305
306 return emailMessage;
307 }
308
309
310
311
312
313
314
315
316
317
318
319
320
321 protected void validateSend(
322 final Wiser mailServer,
323 final String strSubject,
324 final Multipart content,
325 final InternetAddress fromAdd,
326 final List<InternetAddress> toAdd,
327 final List<InternetAddress> ccAdd,
328 final List<InternetAddress> bccAdd,
329 final boolean boolSaveToFile)
330 throws IOException
331 {
332
333 final WiserMessage emailMessage = this.validateSend(
334 mailServer,
335 strSubject,
336 fromAdd,
337 toAdd,
338 ccAdd,
339 bccAdd,
340 boolSaveToFile);
341
342
343
344
345 final String strSentContent =
346 content.getContentType();
347
348
349 final String emailMessageBody = getMessageBody(emailMessage);
350 final String strMessageBody =
351 emailMessageBody.substring(AbstractEmailTest.BODY_START_PAD,
352 emailMessageBody.length()
353 - AbstractEmailTest.BODY_END_PAD);
354 assertTrue("didn't find expected content type in message body",
355 strMessageBody.contains(strSentContent));
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369
370 protected void validateSend(
371 final Wiser mailServer,
372 final String strSubject,
373 final String strMessage,
374 final InternetAddress fromAdd,
375 final List<InternetAddress> toAdd,
376 final List<InternetAddress> ccAdd,
377 final List<InternetAddress> bccAdd,
378 final boolean boolSaveToFile)
379 throws IOException
380 {
381
382 final WiserMessage emailMessage = this.validateSend(
383 mailServer,
384 strSubject,
385 fromAdd,
386 toAdd,
387 ccAdd,
388 bccAdd,
389 true);
390
391
392 assertThat("didn't find expected message content in message body",
393 getMessageBody(emailMessage), containsString(strMessage));
394 }
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412 private String serializeEmailMessage(final WiserMessage wiserMessage)
413 throws MessagingException, IOException
414 {
415 if (wiserMessage == null)
416 {
417 return "";
418 }
419
420 final StringBuffer serializedEmail = new StringBuffer();
421 final MimeMessage message = wiserMessage.getMimeMessage();
422
423
424 for (final Enumeration<?> headers = message.getAllHeaders(); headers
425 .hasMoreElements();)
426 {
427 final Header header = (Header) headers.nextElement();
428 serializedEmail.append(header.getName());
429 serializedEmail.append(": ");
430 serializedEmail.append(header.getValue());
431 serializedEmail.append(LINE_SEPARATOR);
432 }
433
434
435 final byte[] messageBody = getMessageBodyBytes(message);
436
437 serializedEmail.append(LINE_SEPARATOR);
438 serializedEmail.append(messageBody);
439 serializedEmail.append(LINE_SEPARATOR);
440
441 return serializedEmail.toString();
442 }
443
444
445
446
447
448
449
450
451
452
453
454
455 private String getMessageBody(final WiserMessage wiserMessage)
456 throws IOException
457 {
458 if (wiserMessage == null)
459 {
460 return "";
461 }
462
463 byte[] messageBody = null;
464
465 try
466 {
467 final MimeMessage message = wiserMessage.getMimeMessage();
468 messageBody = getMessageBodyBytes(message);
469 }
470 catch (final MessagingException me)
471 {
472
473
474 final IllegalStateException ise =
475 new IllegalStateException("couldn't process MimeMessage from WiserMessage in getMessageBody()");
476 ise.initCause(me);
477 throw ise;
478 }
479
480 return messageBody != null ? new String(messageBody).intern() : "";
481 }
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497 private byte[] getMessageBodyBytes(final MimeMessage mimeMessage)
498 throws IOException, MessagingException
499 {
500 final DataHandler dataHandler = mimeMessage.getDataHandler();
501 final ByteArrayOutputStream byteArrayOutStream = new ByteArrayOutputStream();
502 final BufferedOutputStream buffOs = new BufferedOutputStream(
503 byteArrayOutStream);
504 dataHandler.writeTo(buffOs);
505 buffOs.flush();
506
507 return byteArrayOutStream.toByteArray();
508 }
509
510
511
512
513
514
515
516
517
518
519 protected boolean isMailServerStopped(final Wiser fakeMailServer) {
520 return !fakeMailServer.getServer().isRunning();
521 }
522
523
524
525
526
527
528
529
530
531
532 protected URL createInvalidURL() throws Exception {
533 final URL url = createMock(URL.class);
534 expect(url.openStream()).andThrow(new IOException());
535 replay(url);
536
537 return url;
538 }
539 }