View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.mail2.jakarta.util;
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.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.io.File;
26  import java.nio.file.Paths;
27  import java.util.List;
28  import java.util.Properties;
29  
30  import org.apache.commons.mail2.jakarta.HtmlEmail;
31  import org.junit.jupiter.api.Test;
32  
33  import jakarta.activation.DataSource;
34  import jakarta.mail.Session;
35  import jakarta.mail.internet.MimeMessage;
36  
37  /**
38   * Tests {@link MimeMessageParser}.
39   */
40  public class MimeMessageParserTest {
41  
42      /**
43       * This test parses a SAP generated email which only contains a PDF but no email text.
44       *
45       * @throws Exception the test failed
46       */
47      @Test
48      public void testAttachmentOnly() throws Exception {
49          final Session session = Session.getDefaultInstance(new Properties());
50          final MimeMessage message = MimeMessageUtils.createMimeMessage(session, Paths.get("./src/test/resources/eml/attachment-only.eml"));
51          final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
52  
53          mimeMessageParser.parse();
54  
55          assertEquals("Kunde 100029   Auftrag   3600", mimeMessageParser.getSubject());
56          assertNotNull(mimeMessageParser.getMimeMessage());
57          assertFalse(mimeMessageParser.isMultipart());
58          assertFalse(mimeMessageParser.hasHtmlContent());
59          assertFalse(mimeMessageParser.hasPlainContent());
60          assertNull(mimeMessageParser.getPlainContent());
61          assertNull(mimeMessageParser.getHtmlContent());
62          assertEquals(1, mimeMessageParser.getTo().size());
63          assertTrue(mimeMessageParser.getCc().isEmpty());
64          assertTrue(mimeMessageParser.getBcc().isEmpty());
65          assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getFrom());
66          assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getReplyTo());
67          assertTrue(mimeMessageParser.hasAttachments());
68          final List<?> attachmentList = mimeMessageParser.getAttachmentList();
69          assertEquals(1, attachmentList.size());
70  
71          final DataSource dataSource = mimeMessageParser.findAttachmentByName("Kunde 100029   Auftrag   3600.pdf");
72          assertNotNull(dataSource);
73          assertEquals("application/pdf", dataSource.getContentType());
74      }
75  
76      /**
77       * This test parses an email which contains a text attachment together with email text.
78       *
79       * @throws Exception the test failed
80       */
81      @Test
82      public void testMultipartTextAttachment() throws Exception {
83          final Session session = Session.getDefaultInstance(new Properties());
84          final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/multipart-text-attachment.eml"));
85          final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
86  
87          mimeMessageParser.parse();
88  
89          assertEquals("test", mimeMessageParser.getSubject());
90          assertNotNull(mimeMessageParser.getMimeMessage());
91          assertTrue(mimeMessageParser.isMultipart());
92          assertFalse(mimeMessageParser.hasHtmlContent());
93          assertTrue(mimeMessageParser.hasPlainContent());
94          assertNotNull(mimeMessageParser.getPlainContent());
95          assertNull(mimeMessageParser.getHtmlContent());
96          assertEquals(1, mimeMessageParser.getTo().size());
97          assertTrue(mimeMessageParser.getCc().isEmpty());
98          assertTrue(mimeMessageParser.getBcc().isEmpty());
99          assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
100         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
101         assertTrue(mimeMessageParser.hasAttachments());
102         final List<?> attachmentList = mimeMessageParser.getAttachmentList();
103         assertEquals(1, attachmentList.size());
104 
105         final DataSource dataSource = mimeMessageParser.findAttachmentByName("test.txt");
106         assertNotNull(dataSource);
107         assertEquals("text/plain", dataSource.getContentType());
108     }
109 
110     /**
111      * This test parses an email which only contains a text attachment with content-disposition: attachment.
112      *
113      * @throws Exception the test failed
114      */
115     @Test
116     public void testMultipartTextAttachmentOnly() throws Exception {
117         final Session session = Session.getDefaultInstance(new Properties());
118         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/multipart-text-attachment-only.eml"));
119         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
120 
121         mimeMessageParser.parse();
122 
123         assertEquals("test", mimeMessageParser.getSubject());
124         assertNotNull(mimeMessageParser.getMimeMessage());
125         assertTrue(mimeMessageParser.isMultipart());
126         assertFalse(mimeMessageParser.hasHtmlContent());
127         assertFalse(mimeMessageParser.hasPlainContent());
128         assertNull(mimeMessageParser.getPlainContent());
129         assertNull(mimeMessageParser.getHtmlContent());
130         assertEquals(1, mimeMessageParser.getTo().size());
131         assertTrue(mimeMessageParser.getCc().isEmpty());
132         assertTrue(mimeMessageParser.getBcc().isEmpty());
133         assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
134         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
135         assertTrue(mimeMessageParser.hasAttachments());
136         final List<?> attachmentList = mimeMessageParser.getAttachmentList();
137         assertEquals(1, attachmentList.size());
138 
139         final DataSource dataSource = mimeMessageParser.findAttachmentByName("test.txt");
140         assertNotNull(dataSource);
141         assertEquals("text/plain", dataSource.getContentType());
142     }
143 
144     @Test
145     public void testParseCreatedHtmlEmailWithMixedContent() throws Exception {
146         final Session session = Session.getDefaultInstance(new Properties());
147         final HtmlEmail email = new HtmlEmail();
148 
149         email.setMailSession(session);
150         email.setFrom("test_from@apache.org");
151         email.setSubject("Test Subject");
152         email.addTo("test_to@apache.org");
153         email.setTextMsg("My test message");
154         email.setHtmlMsg("<p>My HTML message</p>");
155 
156         email.buildMimeMessage();
157         final MimeMessage msg = email.getMimeMessage();
158 
159         final MimeMessageParser mimeMessageParser = new MimeMessageParser(msg);
160         mimeMessageParser.parse();
161 
162         assertEquals("Test Subject", mimeMessageParser.getSubject());
163         assertNotNull(mimeMessageParser.getMimeMessage());
164         assertTrue(mimeMessageParser.isMultipart());
165         assertTrue(mimeMessageParser.hasHtmlContent());
166         assertTrue(mimeMessageParser.hasPlainContent());
167         assertNotNull(mimeMessageParser.getPlainContent());
168         assertNotNull(mimeMessageParser.getHtmlContent());
169         assertEquals(1, mimeMessageParser.getTo().size());
170         assertTrue(mimeMessageParser.getCc().isEmpty());
171         assertTrue(mimeMessageParser.getBcc().isEmpty());
172         assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
173         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
174         assertFalse(mimeMessageParser.hasAttachments());
175     }
176 
177     @Test
178     public void testParseCreatedHtmlEmailWithNoContent() throws Exception {
179         final Session session = Session.getDefaultInstance(new Properties());
180 
181         final HtmlEmail email = new HtmlEmail();
182 
183         email.setMailSession(session);
184         email.setFrom("test_from@apache.org");
185         email.setSubject("Test Subject");
186         email.addTo("test_to@apache.org");
187         email.buildMimeMessage();
188         final MimeMessage msg = email.getMimeMessage();
189 
190         final MimeMessageParser mimeMessageParser = new MimeMessageParser(msg);
191         mimeMessageParser.parse();
192 
193         assertEquals("Test Subject", mimeMessageParser.getSubject());
194         assertNotNull(mimeMessageParser.getMimeMessage());
195         assertTrue(mimeMessageParser.isMultipart());
196         assertFalse(mimeMessageParser.hasHtmlContent());
197         assertFalse(mimeMessageParser.hasPlainContent());
198         assertNull(mimeMessageParser.getPlainContent());
199         assertNull(mimeMessageParser.getHtmlContent());
200         assertEquals(1, mimeMessageParser.getTo().size());
201         assertTrue(mimeMessageParser.getCc().isEmpty());
202         assertTrue(mimeMessageParser.getBcc().isEmpty());
203         assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
204         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
205         assertFalse(mimeMessageParser.hasAttachments());
206     }
207 
208     @Test
209     public void testParseCreatedHtmlEmailWithTextContent() throws Exception {
210         final Session session = Session.getDefaultInstance(new Properties());
211 
212         final HtmlEmail email = new HtmlEmail();
213         email.setMailSession(session);
214         email.setFrom("test_from@apache.org");
215         email.setSubject("Test Subject");
216         email.addTo("test_to@apache.org");
217         email.setTextMsg("My test message");
218 
219         email.buildMimeMessage();
220         final MimeMessage msg = email.getMimeMessage();
221 
222         final MimeMessageParser mimeMessageParser = new MimeMessageParser(msg);
223         mimeMessageParser.parse();
224 
225         assertEquals("Test Subject", mimeMessageParser.getSubject());
226         assertNotNull(mimeMessageParser.getMimeMessage());
227         assertTrue(mimeMessageParser.isMultipart());
228         assertFalse(mimeMessageParser.hasHtmlContent());
229         assertTrue(mimeMessageParser.hasPlainContent());
230         assertNotNull(mimeMessageParser.getPlainContent());
231         assertNull(mimeMessageParser.getHtmlContent());
232         assertEquals(1, mimeMessageParser.getTo().size());
233         assertTrue(mimeMessageParser.getCc().isEmpty());
234         assertTrue(mimeMessageParser.getBcc().isEmpty());
235         assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
236         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
237         assertFalse(mimeMessageParser.hasAttachments());
238     }
239 
240     @Test
241     public void testParseHtmlEmailWithAttachmentAndEncodedFileName() throws Exception {
242         final Session session = Session.getDefaultInstance(new Properties());
243         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/html-attachment-encoded-filename.eml"));
244         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
245 
246         mimeMessageParser.parse();
247 
248         assertEquals("Test HTML Send #1 Subject (w charset)", mimeMessageParser.getSubject());
249         assertNotNull(mimeMessageParser.getMimeMessage());
250         assertTrue(mimeMessageParser.isMultipart());
251         assertTrue(mimeMessageParser.hasHtmlContent());
252         assertTrue(mimeMessageParser.hasPlainContent());
253         assertNotNull(mimeMessageParser.getPlainContent());
254         assertNotNull(mimeMessageParser.getHtmlContent());
255         assertEquals(1, mimeMessageParser.getTo().size());
256         assertTrue(mimeMessageParser.getCc().isEmpty());
257         assertTrue(mimeMessageParser.getBcc().isEmpty());
258         assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
259         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
260         assertTrue(mimeMessageParser.hasAttachments());
261         final List<?> attachmentList = mimeMessageParser.getAttachmentList();
262         assertEquals(1, attachmentList.size());
263 
264         final DataSource dataSource = mimeMessageParser.getAttachmentList().get(0);
265         assertNotNull(dataSource);
266         assertEquals("text/plain", dataSource.getContentType());
267         assertEquals("Test Attachment - a>ä, o>ö, u>ü, au>äu", dataSource.getName());
268     }
269 
270     @Test
271     public void testParseHtmlEmailWithAttachments() throws Exception {
272         final Session session = Session.getDefaultInstance(new Properties());
273         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/html-attachment.eml"));
274         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
275 
276         mimeMessageParser.parse();
277 
278         assertEquals("Test", mimeMessageParser.getSubject());
279         assertNotNull(mimeMessageParser.getMimeMessage());
280         assertTrue(mimeMessageParser.isMultipart());
281         assertTrue(mimeMessageParser.hasHtmlContent());
282         assertTrue(mimeMessageParser.hasPlainContent());
283         assertNotNull(mimeMessageParser.getPlainContent());
284         assertNotNull(mimeMessageParser.getHtmlContent());
285         assertEquals(1, mimeMessageParser.getTo().size());
286         assertTrue(mimeMessageParser.getCc().isEmpty());
287         assertTrue(mimeMessageParser.getBcc().isEmpty());
288         assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getFrom());
289         assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getReplyTo());
290         assertTrue(mimeMessageParser.hasAttachments());
291         final List<?> attachmentList = mimeMessageParser.getAttachmentList();
292         assertEquals(2, attachmentList.size());
293 
294         DataSource dataSource = mimeMessageParser.findAttachmentByName("Wasserlilien.jpg");
295         assertNotNull(dataSource);
296         assertEquals("image/jpeg", dataSource.getContentType());
297 
298         dataSource = mimeMessageParser.findAttachmentByName("it20one.pdf");
299         assertNotNull(dataSource);
300         assertEquals("application/pdf", dataSource.getContentType());
301     }
302 
303     /**
304      * This test parses an email which contains an html attachment with content-disposition: attachment.
305      *
306      * @throws Exception the test failed
307      */
308     @Test
309     public void testParseHtmlEmailWithHtmlAttachment() throws Exception {
310         final Session session = Session.getDefaultInstance(new Properties());
311         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/html-attachment-content-disposition.eml"));
312         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
313 
314         mimeMessageParser.parse();
315 
316         assertEquals("test", mimeMessageParser.getSubject());
317         assertNotNull(mimeMessageParser.getMimeMessage());
318         assertTrue(mimeMessageParser.isMultipart());
319         assertFalse(mimeMessageParser.hasHtmlContent());
320         assertTrue(mimeMessageParser.hasPlainContent());
321         assertNotNull(mimeMessageParser.getPlainContent());
322         assertNull(mimeMessageParser.getHtmlContent());
323         assertEquals(1, mimeMessageParser.getTo().size());
324         assertTrue(mimeMessageParser.getCc().isEmpty());
325         assertTrue(mimeMessageParser.getBcc().isEmpty());
326         assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
327         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
328         assertTrue(mimeMessageParser.hasAttachments());
329         final List<?> attachmentList = mimeMessageParser.getAttachmentList();
330         assertEquals(1, attachmentList.size());
331 
332         final DataSource dataSource = mimeMessageParser.findAttachmentByName("test.html");
333         assertNotNull(dataSource);
334         assertEquals("text/html", dataSource.getContentType());
335     }
336 
337     @Test
338     public void testParseInlineCID() throws Exception {
339         final Session session = Session.getDefaultInstance(new Properties());
340         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/html-attachment.eml"));
341         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
342 
343         mimeMessageParser.parse();
344 
345         assertEquals("Test", mimeMessageParser.getSubject());
346         assertNotNull(mimeMessageParser.getMimeMessage());
347         assertTrue(mimeMessageParser.isMultipart());
348         assertTrue(mimeMessageParser.hasHtmlContent());
349         assertNotNull(mimeMessageParser.getHtmlContent());
350         assertEquals(1, mimeMessageParser.getTo().size());
351         assertTrue(mimeMessageParser.getCc().isEmpty());
352         assertTrue(mimeMessageParser.getBcc().isEmpty());
353         assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getFrom());
354         assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getReplyTo());
355         assertTrue(mimeMessageParser.hasAttachments());
356 
357         assertTrue(mimeMessageParser.getContentIds().contains("part1.01080006.06060206@it20one.at"));
358         assertFalse(mimeMessageParser.getContentIds().contains("part2"));
359 
360         final DataSource ds = mimeMessageParser.findAttachmentByCid("part1.01080006.06060206@it20one.at");
361         assertNotNull(ds);
362         assertEquals(ds, mimeMessageParser.getAttachmentList().get(0));
363     }
364 
365     /**
366      * This test parses an "email read notification" where the resulting data source has no name. Originally the missing name caused a NPE in
367      * MimeUtility.decodeText().
368      *
369      * @throws Exception the test failed
370      */
371     @Test
372     public void testParseMultipartReport() throws Exception {
373         final Session session = Session.getDefaultInstance(new Properties());
374         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/multipart-report.eml"));
375         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
376 
377         mimeMessageParser.parse();
378 
379         assertEquals("Gelesen: ", mimeMessageParser.getSubject());
380         assertNotNull(mimeMessageParser.getMimeMessage());
381         assertTrue(mimeMessageParser.isMultipart());
382         assertTrue(mimeMessageParser.hasHtmlContent());
383         assertFalse(mimeMessageParser.hasPlainContent());
384         assertNull(mimeMessageParser.getPlainContent());
385         assertNotNull(mimeMessageParser.getHtmlContent());
386         assertEquals(1, mimeMessageParser.getTo().size());
387         assertTrue(mimeMessageParser.getCc().isEmpty());
388         assertTrue(mimeMessageParser.getBcc().isEmpty());
389         assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getFrom());
390         assertEquals("siegfried.goeschl@it20one.at", mimeMessageParser.getReplyTo());
391         assertTrue(mimeMessageParser.hasAttachments());
392         final List<?> attachmentList = mimeMessageParser.getAttachmentList();
393         assertEquals(1, attachmentList.size());
394 
395         final DataSource dataSource = (DataSource) attachmentList.get(0);
396         assertNotNull(dataSource);
397         assertNull(dataSource.getName());
398         assertEquals("message/disposition-notification", dataSource.getContentType());
399     }
400 
401     /**
402      * This test parses an eml file published with issue EMAIL-110. This eml file has a corrupted attachment but should not create an OutOfMemoryException.
403      *
404      * @throws Exception the test failed
405      */
406     @Test
407     public void testParseNoHeaderSeperatorWithOutOfMemory() throws Exception {
408         final Session session = Session.getDefaultInstance(new Properties());
409         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/outofmemory-no-header-seperation.eml"));
410         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
411 
412         mimeMessageParser.parse();
413 
414         assertEquals("A corrupt Attachment", mimeMessageParser.getSubject());
415         assertNotNull(mimeMessageParser.getMimeMessage());
416         assertTrue(mimeMessageParser.isMultipart());
417         assertFalse(mimeMessageParser.hasHtmlContent());
418         assertFalse(mimeMessageParser.hasPlainContent());
419         assertNull(mimeMessageParser.getPlainContent());
420         assertNull(mimeMessageParser.getHtmlContent());
421         assertEquals(1, mimeMessageParser.getTo().size());
422         assertEquals(mimeMessageParser.getCc().size(), 0);
423         assertEquals(mimeMessageParser.getBcc().size(), 0);
424     }
425 
426     @Test
427     public void testParseSimpleEmail() throws Exception {
428         final Session session = Session.getDefaultInstance(new Properties());
429         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/simple.eml"));
430         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
431 
432         mimeMessageParser.parse();
433 
434         assertEquals("Test HTML Send #1 Subject (wo charset)", mimeMessageParser.getSubject());
435         assertNotNull(mimeMessageParser.getMimeMessage());
436         assertTrue(mimeMessageParser.isMultipart());
437         assertFalse(mimeMessageParser.hasHtmlContent());
438         assertTrue(mimeMessageParser.hasPlainContent());
439         assertNotNull(mimeMessageParser.getPlainContent());
440         assertNull(mimeMessageParser.getHtmlContent());
441         assertEquals(1, mimeMessageParser.getTo().size());
442         assertTrue(mimeMessageParser.getCc().isEmpty());
443         assertTrue(mimeMessageParser.getBcc().isEmpty());
444         assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
445         assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
446         assertFalse(mimeMessageParser.hasAttachments());
447     }
448 
449     @Test
450     public void testParseSimpleReplyEmail() throws Exception {
451         final Session session = Session.getDefaultInstance(new Properties());
452         final MimeMessage message = MimeMessageUtils.createMimeMessage(session, new File("./src/test/resources/eml/simple-reply.eml"));
453         final MimeMessageParser mimeMessageParser = new MimeMessageParser(message);
454 
455         mimeMessageParser.parse();
456 
457         assertEquals("Re: java.lang.NoClassDefFoundError: org/bouncycastle/asn1/pkcs/PrivateKeyInfo", mimeMessageParser.getSubject());
458         assertNotNull(mimeMessageParser.getMimeMessage());
459         assertFalse(mimeMessageParser.isMultipart());
460         assertFalse(mimeMessageParser.hasHtmlContent());
461         assertTrue(mimeMessageParser.hasPlainContent());
462         assertNotNull(mimeMessageParser.getPlainContent());
463         assertNull(mimeMessageParser.getHtmlContent());
464         assertEquals(1, mimeMessageParser.getTo().size());
465         assertTrue(mimeMessageParser.getCc().isEmpty());
466         assertTrue(mimeMessageParser.getBcc().isEmpty());
467         assertEquals("coheigea@apache.org", mimeMessageParser.getFrom());
468         assertEquals("dev@ws.apache.org", mimeMessageParser.getReplyTo());
469         assertFalse(mimeMessageParser.hasAttachments());
470     }
471 
472 }