1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.mail2.javax;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertTrue;
22 import static org.junit.jupiter.api.Assertions.fail;
23
24 import java.io.BufferedOutputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.io.IOException;
28 import java.net.URL;
29 import java.util.Date;
30 import java.util.Enumeration;
31 import java.util.List;
32
33 import javax.activation.DataHandler;
34 import javax.mail.Header;
35 import javax.mail.MessagingException;
36 import javax.mail.Multipart;
37 import javax.mail.internet.InternetAddress;
38 import javax.mail.internet.MimeMessage;
39
40 import org.apache.commons.mail2.javax.settings.EmailConfiguration;
41 import org.apache.commons.mail2.javax.util.MimeMessageUtils;
42 import org.junit.jupiter.api.AfterEach;
43 import org.junit.jupiter.api.BeforeEach;
44 import org.mockito.Mockito;
45 import org.subethamail.wiser.Wiser;
46 import org.subethamail.wiser.WiserMessage;
47
48
49
50
51 public abstract class AbstractEmailTest {
52
53 public static final int BODY_END_PAD = 3;
54
55
56 public static final int BODY_START_PAD = 2;
57
58
59 private static final String LINE_SEPARATOR = "\r\n";
60
61
62 private static int mailServerPort = 2500;
63
64
65 private static int fileNameCounter;
66
67
68 protected Wiser fakeMailServer;
69
70
71 protected String strTestMailServer = "localhost";
72
73
74 protected String strTestMailFrom = "test_from@apache.org";
75
76
77 protected String strTestMailTo = "test_to@apache.org";
78
79
80 protected String strTestUser = "user";
81
82
83 protected String strTestPasswd = "password";
84
85
86 protected String strTestURL = EmailConfiguration.TEST_URL;
87
88
89 protected String[] testCharsValid = { " ", "a", "A", "\uc5ec", "0123456789", "012345678901234567890" };
90
91
92 protected String[] endOfLineCombinations = { "\n", "\r", "\r\n", "\n\r", };
93
94
95 protected String[] testCharsNotValid = { "", null };
96
97
98 private File emailOutputDir;
99
100
101
102
103
104
105
106
107
108 @SuppressWarnings("resource")
109 protected URL createInvalidURL() throws Exception {
110 URL url = new URL("http://example.invalid");
111 url = Mockito.spy(url);
112 Mockito.doThrow(new IOException("Mocked IOException")).when(url).openStream();
113 return url;
114 }
115
116
117
118
119
120 public void getMailServer() {
121 if (fakeMailServer == null || isMailServerStopped(fakeMailServer)) {
122 mailServerPort++;
123
124 fakeMailServer = new Wiser();
125 fakeMailServer.setPort(getMailServerPort());
126 fakeMailServer.start();
127
128 assertFalse(isMailServerStopped(fakeMailServer), "fake mail server didn't start");
129
130 final Date dtStartWait = new Date();
131 while (isMailServerStopped(fakeMailServer)) {
132
133 if (fakeMailServer != null && !isMailServerStopped(fakeMailServer)) {
134 break;
135 }
136
137
138 if (dtStartWait.getTime() + EmailConfiguration.TIME_OUT <= new Date().getTime()) {
139 fail("Mail server failed to start");
140 }
141 }
142 }
143 }
144
145
146
147
148
149
150 protected int getMailServerPort() {
151 return mailServerPort;
152 }
153
154
155
156
157
158 public String getMessageAsString(final int intMsgNo) {
159 final List<?> receivedMessages = fakeMailServer.getMessages();
160 assertTrue(receivedMessages.size() >= intMsgNo, "mail server didn't get enough messages");
161
162 final WiserMessage emailMessage = (WiserMessage) receivedMessages.get(intMsgNo);
163
164 if (emailMessage != null) {
165 try {
166 return serializeEmailMessage(emailMessage);
167 } catch (final Exception e) {
168
169 }
170 }
171 fail("Message not found");
172 return "";
173 }
174
175
176
177
178
179
180
181
182 private String getMessageBody(final WiserMessage wiserMessage) throws IOException {
183 if (wiserMessage == null) {
184 return "";
185 }
186
187 byte[] messageBody = null;
188
189 try {
190 final MimeMessage message = wiserMessage.getMimeMessage();
191 messageBody = getMessageBodyBytes(message);
192 } catch (final MessagingException e) {
193
194
195 final IllegalStateException rethrow = new IllegalStateException("couldn't process MimeMessage from WiserMessage in getMessageBody()");
196 rethrow.initCause(e);
197 throw rethrow;
198 }
199
200 return messageBody != null ? new String(messageBody).intern() : "";
201 }
202
203
204
205
206
207
208
209
210
211 private byte[] getMessageBodyBytes(final MimeMessage mimeMessage) throws IOException, MessagingException {
212 final DataHandler dataHandler = mimeMessage.getDataHandler();
213 final ByteArrayOutputStream byteArrayOutStream = new ByteArrayOutputStream();
214 final BufferedOutputStream buffOs = new BufferedOutputStream(byteArrayOutStream);
215 dataHandler.writeTo(buffOs);
216 buffOs.flush();
217
218 return byteArrayOutStream.toByteArray();
219 }
220
221
222
223
224
225
226
227 protected boolean isMailServerStopped(final Wiser fakeMailServer) {
228 return !fakeMailServer.getServer().isRunning();
229 }
230
231
232
233
234
235
236
237
238 protected void saveEmailToFile(final WiserMessage email) throws IOException, MessagingException {
239 final int currCounter = fileNameCounter++ % 10;
240 final String emailFileName = "email" + new Date().getTime() + "-" + currCounter + ".eml";
241 final File emailFile = new File(emailOutputDir, emailFileName);
242 MimeMessageUtils.writeMimeMessage(email.getMimeMessage(), emailFile);
243 }
244
245
246
247
248
249
250
251
252
253
254 private String serializeEmailMessage(final WiserMessage wiserMessage) throws MessagingException, IOException {
255 if (wiserMessage == null) {
256 return "";
257 }
258
259 final StringBuilder serializedEmail = new StringBuilder();
260 final MimeMessage message = wiserMessage.getMimeMessage();
261
262
263 for (final Enumeration<?> headers = message.getAllHeaders(); headers.hasMoreElements();) {
264 final Header header = (Header) headers.nextElement();
265 serializedEmail.append(header.getName());
266 serializedEmail.append(": ");
267 serializedEmail.append(header.getValue());
268 serializedEmail.append(LINE_SEPARATOR);
269 }
270
271
272 final byte[] messageBody = getMessageBodyBytes(message);
273
274 serializedEmail.append(LINE_SEPARATOR);
275 serializedEmail.append(messageBody);
276 serializedEmail.append(LINE_SEPARATOR);
277
278 return serializedEmail.toString();
279 }
280
281 @BeforeEach
282 public void setUpAbstractEmailTest() {
283 emailOutputDir = new File("target/test-emails");
284 if (!emailOutputDir.exists()) {
285 emailOutputDir.mkdirs();
286 }
287 }
288
289 protected void stopServer() {
290 if (fakeMailServer != null) {
291 fakeMailServer.stop();
292 }
293 }
294
295 @AfterEach
296 public void tearDownEmailTest() {
297
298 if (fakeMailServer != null && !isMailServerStopped(fakeMailServer)) {
299 fakeMailServer.stop();
300 assertTrue(isMailServerStopped(fakeMailServer), "Mail server didn't stop");
301 }
302
303 fakeMailServer = null;
304 }
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 protected WiserMessage validateSend(final Wiser mailServer, final String strSubject, final InternetAddress fromAdd, final List<InternetAddress> toAdd,
320 final List<InternetAddress> ccAdd, final List<InternetAddress> bccAdd, final boolean boolSaveToFile) throws IOException {
321 assertTrue(mailServer.getMessages().size() == 1, "mail server doesn't contain expected message");
322 final WiserMessage emailMessage = mailServer.getMessages().get(0);
323
324 if (boolSaveToFile) {
325 try {
326 saveEmailToFile(emailMessage);
327 } catch (final MessagingException e) {
328 final IllegalStateException rethrow = new IllegalStateException("caught MessagingException during saving the email");
329 rethrow.initCause(e);
330 throw rethrow;
331 }
332 }
333
334 try {
335
336 final MimeMessage mimeMessage = emailMessage.getMimeMessage();
337
338
339 assertEquals(strSubject, mimeMessage.getHeader("Subject", null), "got wrong subject from mail");
340
341
342 assertEquals(fromAdd.toString(), mimeMessage.getHeader("From", null), "got wrong From: address from mail");
343
344
345 assertTrue(toAdd.toString().contains(mimeMessage.getHeader("To", null)), "got wrong To: address from mail");
346
347
348 if (!ccAdd.isEmpty()) {
349 assertTrue(ccAdd.toString().contains(mimeMessage.getHeader("Cc", null)), "got wrong Cc: address from mail");
350 }
351
352
353 if (!bccAdd.isEmpty()) {
354 assertTrue(bccAdd.toString().contains(mimeMessage.getHeader("Bcc", null)), "got wrong Bcc: address from mail");
355 }
356 } catch (final MessagingException e) {
357 final IllegalStateException rethrow = new IllegalStateException("caught MessagingException in validateSend()");
358 rethrow.initCause(e);
359 throw rethrow;
360 }
361
362 return emailMessage;
363 }
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378 protected void validateSend(final Wiser mailServer, final String strSubject, final Multipart content, final InternetAddress fromAdd,
379 final List<InternetAddress> toAdd, final List<InternetAddress> ccAdd, final List<InternetAddress> bccAdd, final boolean boolSaveToFile)
380 throws IOException {
381
382 final WiserMessage emailMessage = validateSend(mailServer, strSubject, fromAdd, toAdd, ccAdd, bccAdd, boolSaveToFile);
383
384
385
386
387 final String strSentContent = content.getContentType();
388
389
390 final String emailMessageBody = getMessageBody(emailMessage);
391 final String strMessageBody = emailMessageBody.substring(AbstractEmailTest.BODY_START_PAD, emailMessageBody.length() - AbstractEmailTest.BODY_END_PAD);
392 assertTrue(strMessageBody.contains(strSentContent), "didn't find expected content type in message body");
393 }
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408 protected void validateSend(final Wiser mailServer, final String strSubject, final String strMessage, final InternetAddress fromAdd,
409 final List<InternetAddress> toAdd, final List<InternetAddress> ccAdd, final List<InternetAddress> bccAdd, final boolean boolSaveToFile)
410 throws IOException {
411
412 final WiserMessage emailMessage = validateSend(mailServer, strSubject, fromAdd, toAdd, ccAdd, bccAdd, true);
413
414
415 assertTrue(getMessageBody(emailMessage).contains(strMessage), "didn't find expected message content in message body");
416 }
417 }