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.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.assertNotEquals;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.io.File;
27  import java.nio.charset.Charset;
28  import java.nio.charset.IllegalCharsetNameException;
29  import java.nio.charset.StandardCharsets;
30  import java.time.Duration;
31  import java.util.ArrayList;
32  import java.util.Calendar;
33  import java.util.Collections;
34  import java.util.Date;
35  import java.util.HashMap;
36  import java.util.Hashtable;
37  import java.util.List;
38  import java.util.Map;
39  import java.util.Properties;
40  
41  import javax.mail.Message;
42  import javax.mail.Session;
43  import javax.mail.internet.InternetAddress;
44  import javax.mail.internet.MimeMessage;
45  import javax.mail.internet.MimeMultipart;
46  import javax.mail.internet.ParseException;
47  
48  import org.apache.commons.mail2.core.EmailConstants;
49  import org.apache.commons.mail2.core.EmailException;
50  import org.apache.commons.mail2.javax.mocks.MockEmailConcrete;
51  import org.junit.jupiter.api.BeforeEach;
52  import org.junit.jupiter.api.Test;
53  
54  /**
55   * JUnit test case for Email Class
56   */
57  public class EmailTest extends AbstractEmailTest {
58  
59      private static final String[] VALID_EMAILS = { "me@home.com", "joe.doe@apache.org", "someone_here@work-address.com.au" };
60  
61      /** Mock for testing */
62      private MockEmailConcrete email;
63  
64      @BeforeEach
65      public void setUpEmailTest() {
66          // reusable objects to be used across multiple tests
67          email = new MockEmailConcrete();
68      }
69  
70      @Test
71      public void testAddBcc() throws Exception {
72          // Test Success
73          final List<InternetAddress> arrExpected = new ArrayList<>();
74          arrExpected.add(new InternetAddress("me@home.com"));
75          arrExpected.add(new InternetAddress("joe.doe@apache.org"));
76          arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
77  
78          for (final String address : VALID_EMAILS) {
79              email.addBcc(address);
80          }
81  
82          // retrieve and verify
83          assertEquals(arrExpected.size(), email.getBccAddresses().size());
84          assertEquals(arrExpected.toString(), email.getBccAddresses().toString());
85      }
86  
87      @Test
88      public void testAddBcc2() throws Exception {
89          // Test Success
90          final String[] testEmailNames = { "Name1", "", null };
91  
92          final List<InternetAddress> arrExpected = new ArrayList<>();
93          arrExpected.add(new InternetAddress("me@home.com", "Name1"));
94          arrExpected.add(new InternetAddress("joe.doe@apache.org"));
95          arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
96  
97          for (int i = 0; i < VALID_EMAILS.length; i++) {
98              // set from
99              email.addBcc(VALID_EMAILS[i], testEmailNames[i]);
100         }
101 
102         // retrieve and verify
103         assertEquals(arrExpected.size(), email.getBccAddresses().size());
104         assertEquals(arrExpected.toString(), email.getBccAddresses().toString());
105     }
106 
107     @Test
108     public void testAddBccArray() throws Exception {
109         // Test Success
110         final List<InternetAddress> arrExpected = new ArrayList<>();
111         arrExpected.add(new InternetAddress("me@home.com"));
112         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
113         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
114 
115         // add a valid bcc
116         email.addBcc(VALID_EMAILS);
117 
118         // retrieve and verify
119         assertEquals(arrExpected.size(), email.getBccAddresses().size());
120         assertEquals(arrExpected.toString(), email.getBccAddresses().toString());
121     }
122 
123     @Test
124     public void testAddBccBadEncoding() {
125         assertThrows(IllegalCharsetNameException.class, () -> email.addBcc("me@home.com", "me@home.com", "bad.encoding\uc5ec\n"));
126     }
127 
128     @Test
129     public void testAddBccWithEncoding() throws Exception {
130         // Test Success
131         final String testCharset = EmailConstants.ISO_8859_1;
132         final String[] testEmailNames = { "Name1", "", null };
133 
134         final List<InternetAddress> arrExpected = new ArrayList<>();
135         arrExpected.add(new InternetAddress("me@home.com", "Name1", testCharset));
136         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
137         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
138 
139         for (int i = 0; i < VALID_EMAILS.length; i++) {
140             // set bccs
141             email.addBcc(VALID_EMAILS[i], testEmailNames[i], testCharset);
142         }
143 
144         // retrieve and verify
145         assertEquals(arrExpected.size(), email.getBccAddresses().size());
146         assertEquals(arrExpected.toString(), email.getBccAddresses().toString());
147     }
148 
149     @Test
150     public void testAddCc() throws Exception {
151         // Test Success
152         final List<InternetAddress> arrExpected = new ArrayList<>();
153         arrExpected.add(new InternetAddress("me@home.com"));
154         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
155         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
156 
157         for (final String address : VALID_EMAILS) {
158             email.addCc(address);
159         }
160 
161         // retrieve and verify
162         assertEquals(arrExpected.size(), email.getCcAddresses().size());
163         assertEquals(arrExpected.toString(), email.getCcAddresses().toString());
164     }
165 
166     @Test
167     public void testAddCc2() throws Exception {
168         // Test Success
169         final String[] testEmailNames = { "Name1", "", null };
170 
171         final List<InternetAddress> arrExpected = new ArrayList<>();
172         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
173         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
174         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
175 
176         for (int i = 0; i < VALID_EMAILS.length; i++) {
177             // set from
178             email.addCc(VALID_EMAILS[i], testEmailNames[i]);
179         }
180 
181         // retrieve and verify
182         assertEquals(arrExpected.size(), email.getCcAddresses().size());
183         assertEquals(arrExpected.toString(), email.getCcAddresses().toString());
184     }
185 
186     @Test
187     public void testAddCcArray() throws Exception {
188         // Test Success
189         final List<InternetAddress> arrExpected = new ArrayList<>();
190         arrExpected.add(new InternetAddress("me@home.com"));
191         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
192         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
193 
194         // set Cc array
195         email.addCc(VALID_EMAILS);
196 
197         // retrieve and verify
198         assertEquals(arrExpected.size(), email.getCcAddresses().size());
199         assertEquals(arrExpected.toString(), email.getCcAddresses().toString());
200     }
201 
202     @Test
203     public void testAddCcBadEncoding() {
204         assertThrows(IllegalCharsetNameException.class, () -> email.addCc("me@home.com", "me@home.com", "bad.encoding\uc5ec\n"));
205     }
206 
207     @Test
208     public void testAddCcWithEncoding() throws Exception {
209         // Test Success
210         final String testCharset = EmailConstants.ISO_8859_1;
211         final String[] testEmailNames = { "Name1", "", null };
212 
213         final List<InternetAddress> arrExpected = new ArrayList<>();
214         arrExpected.add(new InternetAddress("me@home.com", "Name1", testCharset));
215         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
216         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
217 
218         // add valid ccs
219         for (int i = 0; i < VALID_EMAILS.length; i++) {
220             email.addCc(VALID_EMAILS[i], testEmailNames[i], testCharset);
221         }
222 
223         // retrieve and verify
224         assertEquals(arrExpected.size(), email.getCcAddresses().size());
225         assertEquals(arrExpected.toString(), email.getCcAddresses().toString());
226     }
227 
228     @Test
229     public void testAddHeader() {
230         // Test Success
231         final Map<String, String> headers = new HashMap<>();
232         headers.put("X-Priority", "1");
233         headers.put("Disposition-Notification-To", "me@home.com");
234         headers.put("X-Mailer", "Sendmail");
235 
236         for (final Map.Entry<String, String> header : headers.entrySet()) {
237             final String name = header.getKey();
238             final String value = header.getValue();
239             email.addHeader(name, value);
240         }
241 
242         assertEquals(headers.size(), email.getHeaders().size());
243         assertEquals(headers, email.getHeaders());
244     }
245 
246     @Test
247     public void testAddHeaderEmptyName() {
248         assertThrows(IllegalArgumentException.class, () -> email.addHeader("", "me@home.com"));
249     }
250 
251     @Test
252     public void testAddHeaderEmptyValue() {
253         assertThrows(IllegalArgumentException.class, () -> email.addHeader("X-Mailer", ""));
254     }
255 
256     @Test
257     public void testAddHeaderNullName() {
258         assertThrows(IllegalArgumentException.class, () -> email.addHeader(null, "me@home.com"));
259     }
260 
261     @Test
262     public void testAddHeaderNullValue() {
263         assertThrows(IllegalArgumentException.class, () -> email.addHeader("X-Mailer", null));
264     }
265 
266     @Test
267     public void testAddReplyTo() throws Exception {
268         // Test Success
269         final List<InternetAddress> arrExpected = new ArrayList<>();
270         arrExpected.add(new InternetAddress("me@home.com"));
271         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
272         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
273 
274         for (final String address : VALID_EMAILS) {
275             email.addReplyTo(address);
276         }
277 
278         // retrieve and verify
279         assertEquals(arrExpected.size(), email.getReplyToAddresses().size());
280         assertEquals(arrExpected.toString(), email.getReplyToAddresses().toString());
281     }
282 
283     @Test
284     public void testAddReplyTo2() throws Exception {
285         // Test Success
286         final String[] testEmailNames = { "Name1", "", null };
287 
288         final List<InternetAddress> arrExpected = new ArrayList<>();
289         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
290         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
291         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
292 
293         for (int i = 0; i < VALID_EMAILS.length; i++) {
294             // set replyTo
295             email.addReplyTo(VALID_EMAILS[i], testEmailNames[i]);
296         }
297 
298         // retrieve and verify
299         assertEquals(arrExpected.size(), email.getReplyToAddresses().size());
300         assertEquals(arrExpected.toString(), email.getReplyToAddresses().toString());
301     }
302 
303     @Test
304     public void testAddReplyToBadEncoding() {
305         assertThrows(IllegalCharsetNameException.class, () -> email.addReplyTo("me@home.com", "me@home.com", "bad.encoding\uc5ec\n"));
306     }
307 
308     @Test
309     public void testAddReplyToWithEncoding() throws Exception {
310         // Test Success
311         final String testCharset = EmailConstants.ISO_8859_1;
312         final String[] testEmailNames = { "Name1", "", null };
313 
314         final List<InternetAddress> arrExpected = new ArrayList<>();
315         arrExpected.add(new InternetAddress("me@home.com", "Name1", testCharset));
316         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
317         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
318 
319         for (int i = 0; i < VALID_EMAILS.length; i++) {
320             // set replyTo
321             email.addReplyTo(VALID_EMAILS[i], testEmailNames[i], testCharset);
322         }
323 
324         // retrieve and verify
325         assertEquals(arrExpected.size(), email.getReplyToAddresses().size());
326         assertEquals(arrExpected.toString(), email.getReplyToAddresses().toString());
327     }
328 
329     @Test
330     public void testAddTo() throws Exception {
331         // Test Success
332         final List<InternetAddress> arrExpected = new ArrayList<>();
333         arrExpected.add(new InternetAddress("me@home.com"));
334         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
335         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
336 
337         for (final String address : VALID_EMAILS) {
338             email.addTo(address);
339         }
340 
341         // retrieve and verify
342         assertEquals(arrExpected.size(), email.getToAddresses().size());
343         assertEquals(arrExpected.toString(), email.getToAddresses().toString());
344     }
345 
346     @Test
347     public void testAddTo2() throws Exception {
348         // Test Success
349         final String[] testEmailNames = { "Name1", "", null };
350         final List<InternetAddress> arrExpected = new ArrayList<>();
351         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
352         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
353         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
354 
355         for (int i = 0; i < VALID_EMAILS.length; i++) {
356             // set from
357             email.addTo(VALID_EMAILS[i], testEmailNames[i]);
358         }
359 
360         // retrieve and verify
361         assertEquals(arrExpected.size(), email.getToAddresses().size());
362         assertEquals(arrExpected.toString(), email.getToAddresses().toString());
363     }
364 
365     @Test
366     public void testAddToArray() throws Exception {
367         // Test Success
368         final List<InternetAddress> arrExpected = new ArrayList<>();
369         arrExpected.add(new InternetAddress("me@home.com"));
370         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
371         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
372 
373         // set To
374         email.addTo(VALID_EMAILS);
375 
376         // retrieve and verify
377         assertEquals(arrExpected.size(), email.getToAddresses().size());
378         assertEquals(arrExpected.toString(), email.getToAddresses().toString());
379     }
380 
381     @Test
382     public void testAddToBadEncoding() {
383         assertThrows(IllegalCharsetNameException.class, () -> email.addTo("me@home.com", "me@home.com", "bad.encoding\uc5ec\n"));
384     }
385 
386     @Test
387     public void testAddToWithEncoding() throws Exception {
388         // Test Success
389         final String testCharset = EmailConstants.ISO_8859_1;
390         final String[] testEmailNames = { "Name1", "", null };
391 
392         final List<InternetAddress> arrExpected = new ArrayList<>();
393         arrExpected.add(new InternetAddress("me@home.com", "Name1", testCharset));
394         arrExpected.add(new InternetAddress("joe.doe@apache.org"));
395         arrExpected.add(new InternetAddress("someone_here@work-address.com.au"));
396 
397         for (int i = 0; i < VALID_EMAILS.length; i++) {
398             // set from
399             email.addTo(VALID_EMAILS[i], testEmailNames[i], testCharset);
400         }
401 
402         // retrieve and verify
403         assertEquals(arrExpected.size(), email.getToAddresses().size());
404         assertEquals(arrExpected.toString(), email.getToAddresses().toString());
405     }
406 
407     @Test
408     public void testCorrectContentTypeForPNG() throws Exception {
409         email.setHostName(strTestMailServer);
410         email.setSmtpPort(getMailServerPort());
411         email.setFrom("a@b.com");
412         email.addTo("c@d.com");
413         email.setSubject("test mail");
414 
415         email.setCharset(StandardCharsets.ISO_8859_1.name());
416         final File png = new File("./target/test-classes/images/logos/maven-feather.png");
417         email.setContent(png, "image/png");
418         email.buildMimeMessage();
419         final MimeMessage msg = email.getMimeMessage();
420         msg.saveChanges();
421         assertEquals("image/png", msg.getContentType());
422     }
423 
424     /**
425      * Test: When Email.setCharset() is called, a subsequent setContent() should use that charset for text content types unless overridden by the contentType
426      * parameter. See https://issues.apache.org/jira/browse/EMAIL-1.
427      *
428      *
429      * Case 1: Setting a default charset results in adding that charset info to to the content type of a text/based content object.
430      *
431      * @throws Exception on any error
432      */
433     @Test
434     public void testDefaultCharsetAppliesToTextContent() throws Exception {
435         email.setHostName(strTestMailServer);
436         email.setSmtpPort(getMailServerPort());
437         email.setFrom("a@b.com");
438         email.addTo("c@d.com");
439         email.setSubject("test mail");
440 
441         email.setCharset(StandardCharsets.ISO_8859_1.name());
442         email.setContent("test content", "text/plain");
443         email.buildMimeMessage();
444         final MimeMessage msg = email.getMimeMessage();
445         msg.saveChanges();
446         assertEquals("text/plain; charset=ISO-8859-1", msg.getContentType());
447     }
448 
449     /**
450      * Case 2: A default charset is overridden by an explicitly specified charset in setContent().
451      *
452      * @throws Exception on any error
453      */
454     @Test
455     public void testDefaultCharsetCanBeOverriddenByContentType() throws Exception {
456         email.setHostName(strTestMailServer);
457         email.setSmtpPort(getMailServerPort());
458         email.setFrom("a@b.com");
459         email.addTo("c@d.com");
460         email.setSubject("test mail");
461 
462         email.setCharset(StandardCharsets.ISO_8859_1.name());
463         email.setContent("test content", "text/plain; charset=US-ASCII");
464         email.buildMimeMessage();
465         final MimeMessage msg = email.getMimeMessage();
466         msg.saveChanges();
467         assertEquals("text/plain; charset=US-ASCII", msg.getContentType());
468     }
469 
470     /**
471      * Case 3: A non-text content object ignores a default charset entirely.
472      *
473      * @throws Exception on any error
474      */
475     @Test
476     public void testDefaultCharsetIgnoredByNonTextContent() throws Exception {
477         email.setHostName(strTestMailServer);
478         email.setSmtpPort(getMailServerPort());
479         email.setFrom("a@b.com");
480         email.addTo("c@d.com");
481         email.setSubject("test mail");
482 
483         email.setCharset(StandardCharsets.ISO_8859_1.name());
484         email.setContent("test content", "application/octet-stream");
485         email.buildMimeMessage();
486         final MimeMessage msg = email.getMimeMessage();
487         msg.saveChanges();
488         assertEquals("application/octet-stream", msg.getContentType());
489     }
490 
491     @Test
492     public void testEndOflineCharactersInSubjectAreReplacedWithSpaces() {
493         for (final String invalidChar : endOfLineCombinations) {
494             email.setSubject(invalidChar);
495             assertNotEquals(invalidChar, email.getSubject());
496         }
497         assertEquals("abcdefg", email.setSubject("abcdefg").getSubject());
498         assertEquals("abc defg", email.setSubject("abc\rdefg").getSubject());
499         assertEquals("abc defg", email.setSubject("abc\ndefg").getSubject());
500         assertEquals("abc  defg", email.setSubject("abc\r\ndefg").getSubject());
501         assertEquals("abc  defg", email.setSubject("abc\n\rdefg").getSubject());
502     }
503 
504     @Test
505     public void testFoldingHeaders() throws Exception {
506         email.setHostName(strTestMailServer);
507         email.setSmtpPort(getMailServerPort());
508         email.setFrom("a@b.com");
509         email.addTo("c@d.com");
510         email.setSubject("test mail");
511 
512         final String headerValue = "1234567890 1234567890 123456789 01234567890 123456789 0123456789 01234567890 01234567890";
513         email.addHeader("X-LongHeader", headerValue);
514 
515         assertEquals(1, email.getHeaders().size());
516         // the header should not yet be folded -> will be done by buildMimeMessage()
517         assertFalse(email.getHeaders().get("X-LongHeader").contains("\r\n"));
518 
519         email.buildMimeMessage();
520 
521         final MimeMessage msg = email.getMimeMessage();
522         msg.saveChanges();
523 
524         final String[] values = msg.getHeader("X-LongHeader");
525         assertEquals(1, values.length);
526 
527         // the header should be split in two lines
528         final String[] lines = values[0].split("\\r\\n");
529         assertEquals(2, lines.length);
530 
531         // there should only be one line-break
532         assertEquals(values[0].indexOf("\n"), values[0].lastIndexOf("\n"));
533     }
534 
535     @Test
536     public void testGetHeader() {
537         final Map<String, String> ht = new Hashtable<>();
538         ht.put("X-Foo", "Bar");
539         ht.put("X-Int", "1");
540 
541         email.setHeaders(ht);
542 
543         assertEquals("Bar", email.getHeader("X-Foo"));
544         assertEquals("1", email.getHeader("X-Int"));
545     }
546 
547     @Test
548     public void testGetHeaders() {
549         final Map<String, String> ht = new Hashtable<>();
550         ht.put("X-Foo", "Bar");
551         ht.put("X-Int", "1");
552 
553         email.setHeaders(ht);
554 
555         assertEquals(ht.size(), email.getHeaders().size());
556     }
557 
558     @Test
559     public void testGetSetAuthentication() {
560         // setup
561         final String strUsername = "user.name";
562         final String strPassword = "user.pwd";
563         email.setAuthentication(strUsername, strPassword);
564 
565         // this is cast into DefaultAuthenticator for convenience
566         // and give us access to the getPasswordAuthentication fn
567         final DefaultAuthenticator retrievedAuth = (DefaultAuthenticator) email.getAuthenticator();
568 
569         // tests
570         assertEquals(strUsername, retrievedAuth.getPasswordAuthentication().getUserName());
571         assertEquals(strPassword, retrievedAuth.getPasswordAuthentication().getPassword());
572     }
573 
574     @Test
575     public void testGetSetAuthenticator() {
576         // setup
577         final String strUsername = "user.name";
578         final String strPassword = "user.pwd";
579         final DefaultAuthenticator authenticator = new DefaultAuthenticator(strUsername, strPassword);
580         email.setAuthenticator(authenticator);
581 
582         // this is cast into DefaultAuthenticator for convenience
583         // and give us access to the getPasswordAuthentication fn
584         final DefaultAuthenticator retrievedAuth = (DefaultAuthenticator) email.getAuthenticator();
585 
586         // tests
587         assertEquals(strUsername, retrievedAuth.getPasswordAuthentication().getUserName());
588         assertEquals(strPassword, retrievedAuth.getPasswordAuthentication().getPassword());
589     }
590 
591     @Test
592     public void testGetSetBounceAddress() {
593         assertNull(email.getBounceAddress());
594 
595         final String bounceAddress = "test_bounce@apache.org";
596         email.setBounceAddress(bounceAddress);
597 
598         // tests
599         assertEquals(bounceAddress, email.getBounceAddress());
600     }
601 
602     @Test
603     public void testGetSetCharset() {
604         Charset set = StandardCharsets.US_ASCII;
605         email.setCharset(set.name());
606         assertEquals(set.name(), email.getCharsetName());
607 
608         set = StandardCharsets.UTF_8;
609         email.setCharset(set.name());
610         assertEquals(set.name(), email.getCharsetName());
611     }
612 
613     @Test
614     public void testGetSetDebug() {
615         email.setDebug(true);
616         assertTrue(email.isDebug());
617         email.setDebug(false);
618         assertFalse(email.isDebug());
619     }
620 
621     @Test
622     public void testGetSetHostName() {
623         for (final String validChar : testCharsValid) {
624             email.setHostName(validChar);
625             assertEquals(validChar, email.getHostName());
626         }
627     }
628 
629     @Test
630     public void testGetSetInvalidBounceAddress() {
631         assertThrows(RuntimeException.class, () -> email.setBounceAddress("invalid-bounce-address"));
632     }
633 
634     @Test
635     public void testGetSetSentDate() {
636         // with input date
637 
638         final Date dtTest = Calendar.getInstance().getTime();
639         email.setSentDate(dtTest);
640         assertEquals(dtTest, email.getSentDate());
641 
642         // with null input (this is a fudge :D)
643         email.setSentDate(null);
644 
645         final Date sentDate = email.getSentDate();
646 
647         // Date objects are millisecond specific. If you have a slow processor,
648         // time passes between the generation of dtTest and the new Date() in
649         // getSentDate() and this test fails. Make sure that the difference
650         // is less than a second...
651         assertTrue(Math.abs(sentDate.getTime() - dtTest.getTime()) < 1000);
652     }
653 
654     @Test
655     public void testGetSetSession() throws Exception {
656 
657         final Properties properties = new Properties(System.getProperties());
658         properties.setProperty(EmailConstants.MAIL_TRANSPORT_PROTOCOL, EmailConstants.SMTP);
659 
660         properties.setProperty(EmailConstants.MAIL_PORT, String.valueOf(getMailServerPort()));
661         properties.setProperty(EmailConstants.MAIL_HOST, strTestMailServer);
662         properties.setProperty(EmailConstants.MAIL_DEBUG, String.valueOf(false));
663 
664         final Session mySession = Session.getInstance(properties, null);
665 
666         email.setMailSession(mySession);
667         assertEquals(mySession, email.getMailSession());
668 
669     }
670 
671     @Test
672     public void testGetSetSmtpPort() {
673         email.setSmtpPort(1);
674         assertEquals(1, Integer.parseInt(email.getSmtpPort()));
675 
676         email.setSmtpPort(Integer.MAX_VALUE);
677         assertEquals(Integer.MAX_VALUE, Integer.parseInt(email.getSmtpPort()));
678     }
679 
680     @Test
681     public void testSendBadAuthSet() throws Exception {
682         getMailServer();
683 
684         email = new MockEmailConcrete();
685         email.setHostName(strTestMailServer);
686         email.setSmtpPort(getMailServerPort());
687         email.setFrom(strTestMailFrom);
688         email.addTo(strTestMailTo);
689         email.setAuthentication(null, null);
690 
691         assertThrows(EmailException.class, email::send);
692     }
693 
694     @Test
695     public void testSendBadHostName() {
696         final EmailException e = assertThrows(EmailException.class, () -> {
697             getMailServer();
698             email = new MockEmailConcrete();
699             email.setSubject("Test Email #1 Subject");
700             email.setHostName("bad.host.com");
701             email.setFrom("me@home.com");
702             email.addTo("me@home.com");
703             email.addCc("me@home.com");
704             email.addBcc("me@home.com");
705             email.addReplyTo("me@home.com");
706             email.setContent("test string object", " ; charset=" + EmailConstants.US_ASCII);
707             email.send();
708         });
709         assertTrue(e.getCause() instanceof ParseException);
710         stopServer();
711     }
712 
713     @Test
714     public void testSendCorrectSmtpPortContainedInException() {
715         final EmailException e = assertThrows(EmailException.class, () -> {
716             getMailServer();
717 
718             email = new MockEmailConcrete();
719             email.setHostName("bad.host.com");
720             email.setSSLOnConnect(true);
721             email.setFrom(strTestMailFrom);
722             email.addTo(strTestMailTo);
723             email.setAuthentication(null, null);
724             email.send();
725         });
726         assertTrue(e.getMessage().contains("bad.host.com:465"));
727         stopServer();
728     }
729 
730     @Test
731     public void testSendDestinationNotSet() throws Exception {
732         getMailServer();
733 
734         email = new MockEmailConcrete();
735         email.setHostName(strTestMailServer);
736         email.setSmtpPort(getMailServerPort());
737         email.setFrom("me@home.com");
738 
739         assertThrows(EmailException.class, email::send);
740     }
741 
742     @Test
743     public void testSendFromNotSet() throws Exception {
744         getMailServer();
745 
746         email = new MockEmailConcrete();
747         email.setHostName(strTestMailServer);
748         email.setSmtpPort(getMailServerPort());
749         email.addTo("me@home.com");
750 
751         assertThrows(EmailException.class, email::send);
752     }
753 
754     @Test
755     public void testSendFromSetInSession() throws Exception {
756         getMailServer();
757 
758         email = new MockEmailConcrete();
759         email.setHostName(strTestMailServer);
760         email.setSmtpPort(getMailServerPort());
761         email.addTo("me@home.com");
762         email.getMailSession().getProperties().setProperty(EmailConstants.MAIL_FROM, "me@home.com");
763 
764         email.send();
765     }
766 
767     @Test
768     public void testSendNoHostName() {
769         getMailServer();
770 
771         email = new MockEmailConcrete();
772 
773         assertThrows(EmailException.class, email::send);
774     }
775 
776     @Test
777     public void testSetBcc() throws Exception {
778         // Test Success
779         final List<InternetAddress> testInetEmailValid = new ArrayList<>();
780         testInetEmailValid.add(new InternetAddress("me@home.com", "Name1"));
781         testInetEmailValid.add(new InternetAddress("joe.doe@apache.org", "joe.doe@apache.org"));
782         testInetEmailValid.add(new InternetAddress("someone_here@work-address.com.au", "someone_here@work-address.com.au"));
783 
784         email.setBcc(testInetEmailValid);
785         assertEquals(testInetEmailValid, email.getBccAddresses());
786     }
787 
788     @Test
789     public void testSetBccEmpty() {
790         assertThrows(EmailException.class, () -> email.setBcc(Collections.<InternetAddress>emptyList()));
791     }
792 
793     @Test
794     public void testSetBccNull() {
795         assertThrows(EmailException.class, () -> email.setBcc(null));
796     }
797 
798     @Test
799     public void testSetCc() throws Exception {
800         // Test Success
801         final List<InternetAddress> testEmailValid2 = new ArrayList<>();
802         testEmailValid2.add(new InternetAddress("Name1 <me@home.com>"));
803         testEmailValid2.add(new InternetAddress("\"joe.doe@apache.org\" <joe.doe@apache.org>"));
804         testEmailValid2.add(new InternetAddress("\"someone_here@work.com.au\" <someone_here@work.com.au>"));
805 
806         email.setCc(testEmailValid2);
807         assertEquals(testEmailValid2, email.getCcAddresses());
808     }
809 
810     @Test
811     public void testSetCcEmpty() {
812         assertThrows(EmailException.class, () -> email.setCc(Collections.<InternetAddress>emptyList()));
813     }
814 
815     @Test
816     public void testSetCcNull() {
817         assertThrows(EmailException.class, () -> email.setCc(null));
818     }
819 
820     @Test
821     public void testSetContentEmptyMimeMultipart() {
822         final MimeMultipart part = new MimeMultipart();
823         email.setContent(part);
824 
825         assertEquals(part, email.getEmailBody());
826     }
827 
828     @Test
829     public void testSetContentMimeMultipart() {
830         final MimeMultipart part = new MimeMultipart("abc123");
831         email.setContent(part);
832 
833         assertEquals(part, email.getEmailBody());
834     }
835 
836     @Test
837     public void testSetContentNull() throws Exception {
838         email.setContent(null);
839         assertNull(email.getEmailBody());
840     }
841 
842     @Test
843     public void testSetContentObject() {
844         // test (string object and valid content type)
845         String testObject = "test string object";
846         String testContentType = " ; charset=" + EmailConstants.US_ASCII;
847 
848         email.setContent(testObject, testContentType);
849         assertEquals(testObject, email.getContent());
850         assertEquals(testContentType, email.getContentType());
851 
852         // test (null string object and valid content type)
853         testObject = null;
854         testContentType = " ; charset=" + EmailConstants.US_ASCII + " some more here";
855 
856         email.setContent(testObject, testContentType);
857         assertEquals(testObject, email.getContent());
858         assertEquals(testContentType, email.getContentType());
859 
860         // test (string object and null content type)
861         testObject = "test string object";
862         testContentType = null;
863 
864         email.setContent(testObject, testContentType);
865         assertEquals(testObject, email.getContent());
866         assertEquals(testContentType, email.getContentType());
867 
868         // test (string object and invalid content type)
869         testObject = "test string object";
870         testContentType = " something incorrect ";
871 
872         email.setContent(testObject, testContentType);
873         assertEquals(testObject, email.getContent());
874         assertEquals(testContentType, email.getContentType());
875     }
876 
877     @Test
878     public void testSetFrom() throws Exception {
879         // Test Success
880         final List<InternetAddress> arrExpected = new ArrayList<>();
881         arrExpected.add(new InternetAddress("me@home.com", "me@home.com"));
882         arrExpected.add(new InternetAddress("joe.doe@apache.org", "joe.doe@apache.org"));
883         arrExpected.add(new InternetAddress("someone_here@work-address.com.au", "someone_here@work-address.com.au"));
884 
885         for (int i = 0; i < VALID_EMAILS.length; i++) {
886 
887             // set from
888             email.setFrom(VALID_EMAILS[i]);
889 
890             // retrieve and verify
891             assertEquals(arrExpected.get(i), email.getFromAddress());
892         }
893     }
894 
895     @Test
896     public void testSetFrom2() throws Exception {
897         // Test Success
898         final String[] testEmailNames = { "Name1", "", null };
899         final List<InternetAddress> arrExpected = new ArrayList<>();
900         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
901         arrExpected.add(new InternetAddress("joe.doe@apache.org", "joe.doe@apache.org"));
902         arrExpected.add(new InternetAddress("someone_here@work-address.com.au", "someone_here@work-address.com.au"));
903 
904         for (int i = 0; i < VALID_EMAILS.length; i++) {
905             // set from
906             email.setFrom(VALID_EMAILS[i], testEmailNames[i]);
907 
908             // retrieve and verify
909             assertEquals(arrExpected.get(i), email.getFromAddress());
910 
911         }
912     }
913 
914     @Test
915     public void testSetFromBadEncoding() {
916         assertThrows(IllegalCharsetNameException.class, () -> email.setFrom("me@home.com", "me@home.com", "bad.encoding\uc5ec\n"));
917     }
918 
919     @Test
920     public void testSetFromWithEncoding() throws Exception {
921         // Test Success (with charset set)
922         final String testValidEmail = "me@home.com";
923 
924         final InternetAddress inetExpected = new InternetAddress("me@home.com", "me@home.com", EmailConstants.ISO_8859_1);
925 
926         // set from
927         email.setFrom(testValidEmail, testValidEmail, EmailConstants.ISO_8859_1);
928 
929         // retrieve and verify
930         assertEquals(inetExpected, email.getFromAddress());
931 
932     }
933 
934     @Test
935     public void testSetHeaderEmptyName() {
936         assertThrows(IllegalArgumentException.class, () -> email.setHeaders(Collections.singletonMap("", "me@home.com")));
937     }
938 
939     @Test
940     public void testSetHeaderEmptyValue() {
941         assertThrows(IllegalArgumentException.class, () -> email.setHeaders(Collections.singletonMap("X-Mailer", "")));
942 
943     }
944 
945     @Test
946     public void testSetHeaderNullName() {
947         assertThrows(IllegalArgumentException.class, () -> email.setHeaders(Collections.singletonMap((String) null, "me@home.com")));
948     }
949 
950     @Test
951     public void testSetHeaderNullValue() {
952         assertThrows(IllegalArgumentException.class, () -> email.setHeaders(Collections.singletonMap("X-Mailer", (String) null)));
953     }
954 
955     @Test
956     public void testSetHeaders() {
957         final Map<String, String> ht = new Hashtable<>();
958         ht.put("X-Priority", "1");
959         ht.put("Disposition-Notification-To", "me@home.com");
960         ht.put("X-Mailer", "Sendmail");
961 
962         email.setHeaders(ht);
963 
964         assertEquals(ht.size(), email.getHeaders().size());
965         assertEquals(ht, email.getHeaders());
966     }
967 
968     @Test
969     public void testSetNullAndEmptyBounceAddress() {
970         assertNull(email.setBounceAddress(null).getBounceAddress());
971         assertEquals("", email.setBounceAddress("").getBounceAddress());
972     }
973 
974     @Test
975     public void testSetPopBeforeSmtp() {
976         // simple test (can be improved)
977         final boolean boolPopBeforeSmtp = true;
978         final String strHost = "mail.home.com";
979         final String strUsername = "user.name";
980         final String strPassword = "user.passwd";
981 
982         email.setPopBeforeSmtp(boolPopBeforeSmtp, strHost, strUsername, strPassword);
983 
984         // retrieve and verify
985         assertEquals(boolPopBeforeSmtp, email.isPopBeforeSmtp());
986         assertEquals(strHost, email.getPopHost());
987         assertEquals(strUsername, email.getPopUserName());
988         assertEquals(strPassword, email.getPopPassword());
989     }
990 
991     @Test
992     public void testSetSmptPortNegative() {
993         assertThrows(IllegalArgumentException.class, () -> email.setSmtpPort(-1));
994     }
995 
996     @Test
997     public void testSetSmtpPortMinValue() {
998         assertThrows(IllegalArgumentException.class, () -> email.setSmtpPort(Integer.MIN_VALUE));
999     }
1000 
1001     @Test
1002     public void testSetSmtpPortZero() {
1003         assertThrows(IllegalArgumentException.class, () -> email.setSmtpPort(0));
1004     }
1005 
1006     @Test
1007     public void testSetSubjectValid() {
1008         for (final String validChar : testCharsValid) {
1009             email.setSubject(validChar);
1010             assertEquals(validChar, email.getSubject());
1011         }
1012         assertNull(email.setSubject(null).getSubject());
1013         assertEquals("", email.setSubject("").getSubject());
1014         assertEquals("   ", email.setSubject("   ").getSubject());
1015         assertEquals("\t", email.setSubject("\t").getSubject());
1016     }
1017 
1018     @Test
1019     public void testSetTo() throws Exception {
1020         // Test Success
1021         final List<InternetAddress> testEmailValid2 = new ArrayList<>();
1022         testEmailValid2.add(new InternetAddress("me@home.com", "Name1"));
1023         testEmailValid2.add(new InternetAddress("joe.doe@apache.org", "joe.doe@apache.org"));
1024         testEmailValid2.add(new InternetAddress("someone_here@work-address.com.au", "someone_here@work-address.com.au"));
1025 
1026         email.setTo(testEmailValid2);
1027 
1028         // retrieve and verify
1029         assertEquals(testEmailValid2.size(), email.getToAddresses().size());
1030         assertEquals(testEmailValid2.toString(), email.getToAddresses().toString());
1031     }
1032 
1033     @Test
1034     public void testSetToEmpty() {
1035         assertThrows(EmailException.class, () -> email.setTo(Collections.<InternetAddress>emptyList()));
1036     }
1037 
1038     @Test
1039     public void testSetToNull() {
1040         assertThrows(EmailException.class, () -> email.setTo(null));
1041     }
1042 
1043     @Test
1044     public void testSocketConnectionTimeout() {
1045         assertEquals(EmailConstants.SOCKET_TIMEOUT.toMillis(), email.getSocketConnectionTimeout());
1046         email.setSocketConnectionTimeout(Duration.ofMillis(5678));
1047         assertEquals(5678, email.getSocketConnectionTimeout());
1048     }
1049 
1050     @Test
1051     public void testSocketTimeout() {
1052         assertEquals(EmailConstants.SOCKET_TIMEOUT.toMillis(), email.getSocketTimeout());
1053         email.setSocketTimeout(Duration.ofMillis(5678));
1054         assertEquals(5678, email.getSocketTimeout());
1055     }
1056 
1057     @Test
1058     public void testSupportForInternationalDomainNames() throws Exception {
1059         email.setHostName(strTestMailServer);
1060         email.setSmtpPort(getMailServerPort());
1061         email.setFrom("from@d\u00F6m\u00E4in.example");
1062         email.addTo("to@d\u00F6m\u00E4in.example");
1063         email.addCc("cc@d\u00F6m\u00E4in.example");
1064         email.addBcc("bcc@d\u00F6m\u00E4in.example");
1065         email.setSubject("test mail");
1066         email.setSubject("testSupportForInternationalDomainNames");
1067         email.setMsg("This is a test mail ... :-)");
1068 
1069         email.buildMimeMessage();
1070         final MimeMessage msg = email.getMimeMessage();
1071 
1072         assertEquals("from@xn--dmin-moa0i.example", msg.getFrom()[0].toString());
1073         assertEquals("to@xn--dmin-moa0i.example", msg.getRecipients(Message.RecipientType.TO)[0].toString());
1074         assertEquals("cc@xn--dmin-moa0i.example", msg.getRecipients(Message.RecipientType.CC)[0].toString());
1075         assertEquals("bcc@xn--dmin-moa0i.example", msg.getRecipients(Message.RecipientType.BCC)[0].toString());
1076     }
1077 
1078     @Test
1079     public void testToInternetAddressArray() throws Exception {
1080         final List<InternetAddress> testInetEmailValid = new ArrayList<>();
1081 
1082         testInetEmailValid.add(new InternetAddress("me@home.com", "Name1"));
1083         testInetEmailValid.add(new InternetAddress("joe.doe@apache.org", "joe.doe@apache.org"));
1084         testInetEmailValid.add(new InternetAddress("someone_here@work-address.com.au", "someone_here@work-address.com.au"));
1085 
1086         email.setBcc(testInetEmailValid);
1087         assertEquals(testInetEmailValid.size(), email.getBccAddresses().size());
1088     }
1089 
1090 }