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.mail;
18  
19  import java.io.UnsupportedEncodingException;
20  import java.nio.charset.Charset;
21  import java.nio.charset.IllegalCharsetNameException;
22  import java.util.ArrayList;
23  import java.util.Calendar;
24  import java.util.Date;
25  import java.util.Hashtable;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Properties;
30  
31  import javax.mail.Authenticator;
32  import javax.mail.Session;
33  import javax.mail.internet.InternetAddress;
34  import javax.mail.internet.MimeMessage;
35  import javax.mail.internet.MimeMultipart;
36  import javax.mail.internet.ParseException;
37  
38  import org.apache.commons.mail.mocks.MockEmailConcrete;
39  
40  /**
41   * JUnit test case for Email Class
42   *
43   * @since 1.0
44   * @author <a href="mailto:corey.scott@gmail.com">Corey Scott</a>
45   * @version $Id: EmailTest.java 513307 2007-03-01 13:22:34Z dion $
46   */
47  
48  public class EmailTest extends BaseEmailTestCase
49  {
50      /** valid email addresses */
51      public static final String[] ARR_VALID_EMAILS =
52          {
53              "me@home.com",
54              "joe.doe@apache.org",
55              "someone_here@work-address.com.au"};
56  
57      /** mock for testing */
58      private MockEmailConcrete email;
59  
60      /**
61       * @param name test name
62       */
63      public EmailTest(String name)
64      {
65          super(name);
66      }
67  
68      /**
69       * @throws Exception  */
70      protected void setUp() throws Exception
71      {
72          super.setUp();
73          // reusable objects to be used across multiple tests
74          this.email = new MockEmailConcrete();
75      }
76  
77      /** */
78      public void testGetSetDebug()
79      {
80          // JUnitDoclet begin method setBoolTest isBoolTest
81          boolean[] tests = {true, false};
82  
83          for (int i = 0; i < tests.length; i++)
84          {
85              this.email.setDebug(tests[i]);
86              assertEquals(tests[i], this.email.isDebug());
87          }
88      }
89  
90      /**
91       *
92       * @throws Exception Exception
93       */
94      public void testGetSetSession() throws Exception
95      {
96  
97          Properties properties = new Properties(System.getProperties());
98          properties.setProperty(Email.MAIL_TRANSPORT_PROTOCOL, Email.SMTP);
99  
100         properties.setProperty(
101             Email.MAIL_PORT,
102             String.valueOf(this.getMailServerPort()));
103         properties.setProperty(Email.MAIL_HOST, this.strTestMailServer);
104         properties.setProperty(Email.MAIL_DEBUG, String.valueOf(false));
105 
106         Session mySession = Session.getInstance(properties, null);
107 
108         this.email.setMailSession(mySession);
109         assertEquals(mySession, this.email.getMailSession());
110 
111     }
112 
113     /** */
114     public void testGetSetAuthentication()
115     {
116         // setup
117         String strUsername = "user.name";
118         String strPassword = "user.pwd";
119         this.email.setAuthentication(strUsername, strPassword);
120 
121         // this is cast into DefaultAuthenticator for convenience
122         // and give us access to the getPasswordAuthentication fn
123         DefaultAuthenticator retrievedAuth =
124             (DefaultAuthenticator) this.email.getAuthenticator();
125 
126         // tests
127         assertTrue(
128             Authenticator.class.isInstance(this.email.getAuthenticator()));
129         assertEquals(
130             strUsername,
131             retrievedAuth.getPasswordAuthentication().getUserName());
132         assertEquals(
133             strPassword,
134             retrievedAuth.getPasswordAuthentication().getPassword());
135     }
136 
137     /** */
138     public void testGetSetAuthenticator()
139     {
140         // setup
141         String strUsername = "user.name";
142         String strPassword = "user.pwd";
143         DefaultAuthenticator authenicator =
144             new DefaultAuthenticator(strUsername, strPassword);
145         this.email.setAuthenticator(authenicator);
146 
147         // this is cast into DefaultAuthenticator for convenience
148         // and give us access to the getPasswordAuthentication fn
149         DefaultAuthenticator retrievedAuth =
150             (DefaultAuthenticator) this.email.getAuthenticator();
151 
152         // tests
153         assertTrue(
154             Authenticator.class.isInstance(this.email.getAuthenticator()));
155         assertEquals(
156             strUsername,
157             retrievedAuth.getPasswordAuthentication().getUserName());
158         assertEquals(
159             strPassword,
160             retrievedAuth.getPasswordAuthentication().getPassword());
161     }
162 
163     /** */
164     public void testGetSetCharset()
165     {
166         // test ASCII and UTF-8 charsets; since every JVM is required
167         // to support these, testing them should always succeed.
168         Charset set = Charset.forName("US-ASCII");
169         this.email.setCharset(set.name());
170         assertEquals(set.name(), this.email.getCharset());
171 
172         set = Charset.forName("UTF-8");
173         this.email.setCharset(set.name());
174         assertEquals(set.name(), this.email.getCharset());
175     }
176 
177     /** */
178     public void testSetContentMimeMultipart()
179     {
180         MimeMultipart[] tests =
181             {new MimeMultipart(), new MimeMultipart("abc123"), null};
182 
183         for (int i = 0; i < tests.length; i++)
184         {
185             this.email.setContent(tests[i]);
186             assertEquals(tests[i], this.email.getContentMimeMultipart());
187         }
188     }
189 
190     /** */
191     public void testSetContentObject()
192     {
193         // setup
194         String testObject = "test string object";
195         String testContentType = "";
196 
197         // ====================================================================
198         // test (string object and valid content type)
199         testObject = "test string object";
200         testContentType = " ; charset=" + Email.US_ASCII;
201 
202         this.email.setContent(testObject, testContentType);
203         assertEquals(testObject, this.email.getContentObject());
204         assertEquals(testContentType, this.email.getContentType());
205 
206         // ====================================================================
207         // test (null string object and valid content type)
208         testObject = null;
209         testContentType = " ; charset=" + Email.US_ASCII + " some more here";
210 
211         this.email.setContent(testObject, testContentType);
212         assertEquals(testObject, this.email.getContentObject());
213         assertEquals(testContentType, this.email.getContentType());
214 
215         // ====================================================================
216         // test (string object and null content type)
217         testObject = "test string object";
218         testContentType = null;
219 
220         this.email.setContent(testObject, testContentType);
221         assertEquals(testObject, this.email.getContentObject());
222         assertEquals(testContentType, this.email.getContentType());
223 
224         // ====================================================================
225         // test (string object and invalid content type)
226         testObject = "test string object";
227         testContentType = " something incorrect ";
228 
229         this.email.setContent(testObject, testContentType);
230         assertEquals(testObject, this.email.getContentObject());
231         assertEquals(testContentType, this.email.getContentType());
232     }
233 
234     /** */
235     public void testGetSetHostName()
236     {
237 
238         for (int i = 0; i < testCharsValid.length; i++)
239         {
240             this.email.setHostName(testCharsValid[i]);
241             assertEquals(testCharsValid[i], this.email.getHostName());
242         }
243     }
244 
245     /** */
246     public void testGetSetSmtpPort()
247     {
248         // ====================================================================
249         // Test Success
250         // ====================================================================
251         int[] tests = {1, Integer.MAX_VALUE};
252 
253         for (int i = 0; i < tests.length; i++)
254         {
255             this.email.setSmtpPort(tests[i]);
256             assertEquals(
257                 tests[i],
258                 Integer.valueOf(this.email.getSmtpPort()).intValue());
259         }
260 
261         // ====================================================================
262         // Test Exceptions
263         // ====================================================================
264         int[] testExs = {Integer.MIN_VALUE, -1, 0};
265 
266         for (int i = 0; i < testExs.length; i++)
267         {
268             try
269             {
270                 this.email.setSmtpPort(testExs[i]);
271                 fail("Should have thrown an exception");
272             }
273             catch (IllegalArgumentException e)
274             {
275                 assertTrue(true);
276             }
277         }
278 
279     }
280 
281     /**
282      *
283      * @throws Exception Exception
284      */
285     public void testSetFrom() throws Exception
286     {
287         // ====================================================================
288         // Test Success
289         // ====================================================================
290 
291         List arrExpected = new ArrayList();
292         arrExpected.add(new InternetAddress("me@home.com", "me@home.com"));
293         arrExpected.add(
294             new InternetAddress(
295                 "joe.doe@apache.org",
296                 "joe.doe@apache.org"));
297         arrExpected.add(
298             new InternetAddress(
299                 "someone_here@work-address.com.au",
300                 "someone_here@work-address.com.au"));
301 
302         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
303         {
304 
305             // set from
306             this.email.setFrom(ARR_VALID_EMAILS[i]);
307 
308             // retrieve and verify
309             assertEquals(arrExpected.get(i), this.email.getFromAddress());
310         }
311     }
312 
313     /**
314      *
315      * @throws Exception Exception
316      */
317     public void testSetFromWithEncoding() throws Exception
318     {
319         // ====================================================================
320         // Test Success (with charset set)
321         // ====================================================================
322         String testValidEmail = "me@home.com";
323 
324         InternetAddress inetExpected =
325             new InternetAddress("me@home.com", "me@home.com", Email.ISO_8859_1);
326 
327         // set from
328         this.email.setFrom(testValidEmail, testValidEmail, Email.ISO_8859_1);
329 
330         // retrieve and verify
331         assertEquals(inetExpected, this.email.getFromAddress());
332 
333     }
334 
335     /**
336      *
337      * @throws Exception Exception
338      */
339     public void testSetFrom2() throws Exception
340     {
341         // ====================================================================
342         // Test Success
343         // ====================================================================
344         String[] testEmails =
345         {
346             "me@home.com",
347             "joe.doe@apache.org",
348             "someone_here@work-address.com.au"
349         };
350         String[] testEmailNames = {"Name1", "", null};
351         List arrExpected = new ArrayList();
352         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
353         arrExpected.add(
354             new InternetAddress(
355                 "joe.doe@apache.org",
356                 "joe.doe@apache.org"));
357         arrExpected.add(
358             new InternetAddress(
359                 "someone_here@work-address.com.au",
360                 "someone_here@work-address.com.au"));
361 
362         for (int i = 0; i < testEmails.length; i++)
363         {
364             // set from
365             this.email.setFrom(testEmails[i], testEmailNames[i]);
366 
367             // retrieve and verify
368             assertEquals(arrExpected.get(i), this.email.getFromAddress());
369 
370         }
371 
372         // ====================================================================
373         // Test Exceptions
374         // ====================================================================
375         // reset the mail class
376         MockEmailConcrete anotherEmail = new MockEmailConcrete();
377 
378         // bad encoding
379         try
380         {
381             // set a dodgy encoding scheme
382             anotherEmail.setFrom("me@home.com", "me@home.com", "bad.encoding\uc5ec\n");
383             fail("setting invalid charset should have failed!");
384         }
385         catch (IllegalCharsetNameException e)
386         {
387             // expected runtime exception.
388         }
389     }
390 
391     /**
392      * @throws EmailException when there are problems adding an address
393      * @throws UnsupportedEncodingException on bad email addresses
394      */
395     public void testAddTo() throws EmailException, UnsupportedEncodingException
396     {
397         // ====================================================================
398         // Test Success
399         // ====================================================================
400 
401         List arrExpected = new ArrayList();
402         arrExpected.add(new InternetAddress("me@home.com", "me@home.com"));
403         arrExpected.add(
404             new InternetAddress(
405                 "joe.doe@apache.org",
406                 "joe.doe@apache.org"));
407         arrExpected.add(
408             new InternetAddress(
409                 "someone_here@work-address.com.au",
410                 "someone_here@work-address.com.au"));
411 
412         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
413         {
414             // set from
415             this.email.addTo(ARR_VALID_EMAILS[i]);
416         }
417 
418         // retrieve and verify
419         assertEquals(arrExpected.size(), this.email.getToList().size());
420         assertEquals(arrExpected.toString(), this.email.getToList().toString());
421     }
422 
423     /**
424      * @throws EmailException when there are problems adding an address
425      * @throws UnsupportedEncodingException on bad email addresses
426      */
427     public void testAddToWithEncoding() throws UnsupportedEncodingException, EmailException
428     {
429         // ====================================================================
430         // Test Success
431         // ====================================================================
432         String testCharset = Email.ISO_8859_1;
433 
434         List arrExpected = new ArrayList();
435         arrExpected.add(
436             new InternetAddress(
437                 "me@home.com",
438                 "me@home.com",
439                 testCharset));
440         arrExpected.add(
441             new InternetAddress(
442                 "joe.doe@apache.org",
443                 "joe.doe@apache.org",
444                 testCharset));
445         arrExpected.add(
446             new InternetAddress(
447                 "someone_here@work-address.com.au",
448                 "someone_here@work-address.com.au",
449                 testCharset));
450 
451         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
452         {
453             // set from
454             this.email.addTo(ARR_VALID_EMAILS[i]);
455         }
456 
457         // retrieve and verify
458         assertEquals(arrExpected.size(), this.email.getToList().size());
459         assertEquals(arrExpected.toString(), this.email.getToList().toString());
460     }
461 
462     /**
463      * @throws EmailException when there are problems adding an address
464      * @throws UnsupportedEncodingException on bad email addresses
465      */
466     public void testAddTo2() throws UnsupportedEncodingException, EmailException
467     {
468         // ====================================================================
469         // Test Success
470         // ====================================================================
471 
472         String[] testEmailNames = {"Name1", "", null};
473 
474         List arrExpected = new ArrayList();
475         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
476         arrExpected.add(
477             new InternetAddress(
478                 "joe.doe@apache.org",
479                 "joe.doe@apache.org"));
480         arrExpected.add(
481             new InternetAddress(
482                 "someone_here@work-address.com.au",
483                 "someone_here@work-address.com.au"));
484 
485         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
486         {
487             // set from
488             this.email.addTo(ARR_VALID_EMAILS[i], testEmailNames[i]);
489         }
490 
491         // retrieve and verify
492         assertEquals(arrExpected.size(), this.email.getToList().size());
493         assertEquals(arrExpected.toString(), this.email.getToList().toString());
494 
495         // ====================================================================
496         // Test Exceptions
497         // ====================================================================
498         // reset the mail class
499         MockEmailConcrete anotherEmail = new MockEmailConcrete();
500 
501         // bad encoding
502         try
503         {
504             // set a dodgy encoding scheme
505             anotherEmail.addTo("me@home.com", "me@home.com", "bad.encoding\uc5ec\n");
506             fail("setting invalid charset should have failed!");
507         }
508         catch (IllegalCharsetNameException  e)
509         {
510             // expected runtime exception.
511         }
512     }
513 
514     /**
515      * @throws EmailException when there are problems adding an address
516      * @throws UnsupportedEncodingException on bad email addresses
517      */
518     public void testSetTo() throws UnsupportedEncodingException, EmailException
519     {
520         // ====================================================================
521         // Test Success
522         // ====================================================================
523         List testEmailValid2 = new ArrayList();
524         testEmailValid2.add(new InternetAddress("me@home.com", "Name1"));
525         testEmailValid2.add(
526             new InternetAddress(
527                 "joe.doe@apache.org",
528                 "joe.doe@apache.org"));
529         testEmailValid2.add(
530             new InternetAddress(
531                 "someone_here@work-address.com.au",
532                 "someone_here@work-address.com.au"));
533 
534         this.email.setTo(testEmailValid2);
535 
536         // retrieve and verify
537         assertEquals(testEmailValid2.size(), this.email.getToList().size());
538         assertEquals(
539             testEmailValid2.toString(),
540             this.email.getToList().toString());
541 
542         // ====================================================================
543         // Exception (Null Input)
544         // ====================================================================
545         try
546         {
547             this.email.setTo(null);
548             fail("Should have thrown an exception");
549         }
550         catch (EmailException e)
551         {
552             assertTrue(true);
553         }
554 
555         // ====================================================================
556         // Exception (Empty Collection)
557         // ====================================================================
558         try
559         {
560             this.email.setTo(new ArrayList());
561             fail("Should have thrown an exception");
562         }
563         catch (EmailException e)
564         {
565             assertTrue(true);
566         }
567     }
568 
569     /**
570      * @throws EmailException when there are problems adding an address
571      * @throws UnsupportedEncodingException on bad email addresses
572      */
573     public void testAddCc() throws UnsupportedEncodingException, EmailException
574     {
575         // ====================================================================
576         // Test Success
577         // ====================================================================
578 
579         List arrExpected = new ArrayList();
580         arrExpected.add(new InternetAddress("me@home.com", "me@home.com"));
581         arrExpected.add(
582             new InternetAddress(
583                 "joe.doe@apache.org",
584                 "joe.doe@apache.org"));
585         arrExpected.add(
586             new InternetAddress(
587                 "someone_here@work-address.com.au",
588                 "someone_here@work-address.com.au"));
589 
590         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
591         {
592             // set from
593             this.email.addCc(ARR_VALID_EMAILS[i]);
594         }
595 
596         // retrieve and verify
597         assertEquals(arrExpected.size(), this.email.getCcList().size());
598         assertEquals(arrExpected.toString(), this.email.getCcList().toString());
599     }
600 
601     /**
602      * @throws EmailException when there are problems adding an address
603      * @throws UnsupportedEncodingException on bad email addresses
604      */
605     public void testAddCcWithEncoding() throws UnsupportedEncodingException, EmailException
606     {
607         // ====================================================================
608         // Test Success
609         // ====================================================================
610         String testCharset = Email.ISO_8859_1;
611 
612         List arrExpected = new ArrayList();
613         arrExpected.add(
614             new InternetAddress(
615                 "me@home.com",
616                 "me@home.com",
617                 testCharset));
618         arrExpected.add(
619             new InternetAddress(
620                 "joe.doe@apache.org",
621                 "joe.doe@apache.org",
622                 testCharset));
623         arrExpected.add(
624             new InternetAddress(
625                 "someone_here@work-address.com.au",
626                 "someone_here@work-address.com.au",
627                 testCharset));
628 
629         // add valid ccs
630         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
631         {
632             this.email.addCc(ARR_VALID_EMAILS[i]);
633         }
634 
635         // retrieve and verify
636         assertEquals(arrExpected.size(), this.email.getCcList().size());
637         assertEquals(arrExpected.toString(), this.email.getCcList().toString());
638     }
639 
640     /**
641      * @throws EmailException when there are problems adding an address
642      * @throws UnsupportedEncodingException on bad email addresses
643      */
644     public void testAddCc2() throws UnsupportedEncodingException, EmailException
645     {
646         // ====================================================================
647         // Test Success
648         // ====================================================================
649 
650         String[] testEmailNames = {"Name1", "", null};
651 
652         List arrExpected = new ArrayList();
653         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
654         arrExpected.add(
655             new InternetAddress(
656                 "joe.doe@apache.org",
657                 "joe.doe@apache.org"));
658         arrExpected.add(
659             new InternetAddress(
660                 "someone_here@work-address.com.au",
661                 "someone_here@work-address.com.au"));
662 
663         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
664         {
665             // set from
666             this.email.addCc(ARR_VALID_EMAILS[i], testEmailNames[i]);
667         }
668 
669         // retrieve and verify
670         assertEquals(arrExpected.size(), this.email.getCcList().size());
671         assertEquals(arrExpected.toString(), this.email.getCcList().toString());
672 
673         // ====================================================================
674         // Test Exceptions
675         // ====================================================================
676         // reset the mail class
677         MockEmailConcrete anotherEmail = new MockEmailConcrete();
678 
679         // bad encoding
680         try
681         {
682             // set a dodgy encoding scheme
683             anotherEmail.addCc("me@home.com", "me@home.com", "bad.encoding\uc5ec\n");
684             fail("setting invalid charset should have failed!");
685         }
686         catch (IllegalCharsetNameException e)
687         {
688             // expected runtime exception.
689         }
690     }
691 
692     /**
693      * @throws EmailException when there are problems adding an address
694      */
695     public void testSetCc() throws EmailException
696     {
697         // ====================================================================
698         // Test Success
699         // ====================================================================
700         List testEmailValid2 = new ArrayList();
701         testEmailValid2.add("Name1 <me@home.com>");
702         testEmailValid2.add("\"joe.doe@apache.org\" <joe.doe@apache.org>");
703         testEmailValid2.add(
704             "\"someone_here@work.com.au\" <someone_here@work.com.au>");
705 
706         this.email.setCc(testEmailValid2);
707         assertEquals(testEmailValid2, this.email.getCcList());
708 
709         // ====================================================================
710         // Exception (Null Input)
711         // ====================================================================
712         try
713         {
714             this.email.setCc(null);
715             fail("Should have thrown an exception");
716         }
717         catch (EmailException e)
718         {
719             assertTrue(true);
720         }
721 
722         // ====================================================================
723         // Exception (Empty Collection)
724         // ====================================================================
725         try
726         {
727             this.email.setCc(new ArrayList());
728             fail("Should have thrown an exception");
729         }
730         catch (EmailException e)
731         {
732             assertTrue(true);
733         }
734     }
735 
736     /**
737      * @throws EmailException when there are problems adding an address
738      * @throws UnsupportedEncodingException on bad email addresses
739      */
740     public void testAddBcc() throws UnsupportedEncodingException, EmailException
741     {
742         // ====================================================================
743         // Test Success
744         // ====================================================================
745 
746         List arrExpected = new ArrayList();
747         arrExpected.add(new InternetAddress("me@home.com", "me@home.com"));
748         arrExpected.add(
749             new InternetAddress(
750                 "joe.doe@apache.org",
751                 "joe.doe@apache.org"));
752         arrExpected.add(
753             new InternetAddress(
754                 "someone_here@work-address.com.au",
755                 "someone_here@work-address.com.au"));
756 
757         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
758         {
759             // add a valid bcc
760             this.email.addBcc(ARR_VALID_EMAILS[i]);
761         }
762 
763         // retrieve and verify
764         assertEquals(arrExpected.size(), this.email.getBccList().size());
765         assertEquals(
766             arrExpected.toString(),
767             this.email.getBccList().toString());
768     }
769 
770     /**
771      * @throws EmailException when there are problems adding an address
772      * @throws UnsupportedEncodingException on bad email addresses
773      */
774     public void testAddBccWithEncoding() throws UnsupportedEncodingException, EmailException
775     {
776         // ====================================================================
777         // Test Success
778         // ====================================================================
779         String testCharset = Email.ISO_8859_1;
780 
781         List arrExpected = new ArrayList();
782         arrExpected.add(
783             new InternetAddress(
784                 "me@home.com",
785                 "me@home.com",
786                 testCharset));
787         arrExpected.add(
788             new InternetAddress(
789                 "joe.doe@apache.org",
790                 "joe.doe@apache.org",
791                 testCharset));
792         arrExpected.add(
793             new InternetAddress(
794                 "someone_here@work-address.com.au",
795                 "someone_here@work-address.com.au",
796                 testCharset));
797 
798         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
799         {
800             // set bccs
801             this.email.addBcc(ARR_VALID_EMAILS[i]);
802         }
803 
804         // retrieve and verify
805         assertEquals(arrExpected.size(), this.email.getBccList().size());
806         assertEquals(
807             arrExpected.toString(),
808             this.email.getBccList().toString());
809     }
810 
811     /**
812      * @throws EmailException when there are problems adding an address
813      * @throws UnsupportedEncodingException on bad email addresses
814      */
815     public void testAddBcc2() throws UnsupportedEncodingException, EmailException
816     {
817         // ====================================================================
818         // Test Success
819         // ====================================================================
820 
821         String[] testEmailNames = {"Name1", "", null};
822 
823 
824         List arrExpected = new ArrayList();
825         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
826         arrExpected.add(
827             new InternetAddress(
828                 "joe.doe@apache.org",
829                 "joe.doe@apache.org"));
830         arrExpected.add(
831             new InternetAddress(
832                 "someone_here@work-address.com.au",
833                 "someone_here@work-address.com.au"));
834 
835         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
836         {
837             // set from
838             this.email.addBcc(ARR_VALID_EMAILS[i], testEmailNames[i]);
839         }
840 
841         // retrieve and verify
842         assertEquals(arrExpected.size(), this.email.getBccList().size());
843         assertEquals(
844             arrExpected.toString(),
845             this.email.getBccList().toString());
846 
847         // ====================================================================
848         // Test Exceptions
849         // ====================================================================
850         // reset the mail class
851         MockEmailConcrete anotherEmail = new MockEmailConcrete();
852 
853         // bad encoding
854         try
855         {
856             // set a dodgy encoding scheme
857             anotherEmail.addBcc("me@home.com", "me@home.com", "bad.encoding\uc5ec\n");
858             fail("setting invalid charset should have failed!");
859         }
860         catch (IllegalCharsetNameException e)
861         {
862             // expected runtime exception.
863         }
864     }
865 
866     /**
867      * @throws EmailException when there are problems adding an address
868      * @throws UnsupportedEncodingException on bad email addresses
869      */
870     public void testSetBcc() throws UnsupportedEncodingException, EmailException
871     {
872         // ====================================================================
873         // Test Success
874         // ====================================================================
875         List testInetEmailValid = new ArrayList();
876         testInetEmailValid.add(new InternetAddress("me@home.com", "Name1"));
877         testInetEmailValid.add(
878             new InternetAddress(
879                 "joe.doe@apache.org",
880                 "joe.doe@apache.org"));
881         testInetEmailValid.add(
882             new InternetAddress(
883                 "someone_here@work-address.com.au",
884                 "someone_here@work-address.com.au"));
885 
886         this.email.setBcc(testInetEmailValid);
887         assertEquals(testInetEmailValid, this.email.getBccList());
888 
889         // ====================================================================
890         // Exception (Null Input)
891         // ====================================================================
892         try
893         {
894             this.email.setBcc(null);
895             fail("Should have thrown an exception");
896         }
897         catch (EmailException e)
898         {
899             assertTrue(true);
900         }
901 
902         // ====================================================================
903         // Exception (Empty Collection)
904         // ====================================================================
905         try
906         {
907             this.email.setBcc(new ArrayList());
908             fail("Should have thrown an exception");
909         }
910         catch (EmailException e)
911         {
912             assertTrue(true);
913         }
914     }
915 
916     /**
917      * @throws EmailException when there are problems adding an address
918      * @throws UnsupportedEncodingException on bad email addresses
919      */
920     public void testAddReplyTo() throws UnsupportedEncodingException, EmailException
921     {
922         // ====================================================================
923         // Test Success
924         // ====================================================================
925 
926         List arrExpected = new ArrayList();
927         arrExpected.add(new InternetAddress("me@home.com", "me@home.com"));
928         arrExpected.add(
929             new InternetAddress(
930                 "joe.doe@apache.org",
931                 "joe.doe@apache.org"));
932         arrExpected.add(
933             new InternetAddress(
934                 "someone_here@work-address.com.au",
935                 "someone_here@work-address.com.au"));
936 
937         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
938         {
939             // set replyTo
940             this.email.addReplyTo(ARR_VALID_EMAILS[i]);
941         }
942 
943         // retrieve and verify
944         assertEquals(arrExpected.size(), this.email.getReplyList().size());
945         assertEquals(
946             arrExpected.toString(),
947             this.email.getReplyList().toString());
948     }
949 
950     /**
951      * @throws EmailException when there are problems adding an address
952      * @throws UnsupportedEncodingException on bad email addresses
953      */
954     public void testAddReplyToWithEncoding() throws UnsupportedEncodingException, EmailException
955     {
956         // ====================================================================
957         // Test Success
958         // ====================================================================
959         String testCharset = Email.ISO_8859_1;
960 
961         List arrExpected = new ArrayList();
962         arrExpected.add(
963             new InternetAddress(
964                 "me@home.com",
965                 "me@home.com",
966                 testCharset));
967         arrExpected.add(
968             new InternetAddress(
969                 "joe.doe@apache.org",
970                 "joe.doe@apache.org",
971                 testCharset));
972         arrExpected.add(
973             new InternetAddress(
974                 "someone_here@work-address.com.au",
975                 "someone_here@work-address.com.au",
976                 testCharset));
977 
978         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
979         {
980             // set replyTo
981             this.email.addReplyTo(ARR_VALID_EMAILS[i]);
982         }
983 
984         // retrieve and verify
985         assertEquals(arrExpected.size(), this.email.getReplyList().size());
986         assertEquals(
987             arrExpected.toString(),
988             this.email.getReplyList().toString());
989     }
990 
991     /**
992      * @throws EmailException when there are problems adding an address
993      * @throws UnsupportedEncodingException on bad email addresses
994      */
995     public void testAddReplyTo2() throws UnsupportedEncodingException, EmailException
996     {
997         // ====================================================================
998         // Test Success
999         // ====================================================================
1000 
1001         String[] testEmailNames = {"Name1", "", null};
1002 
1003         List arrExpected = new ArrayList();
1004         arrExpected.add(new InternetAddress("me@home.com", "Name1"));
1005         arrExpected.add(
1006             new InternetAddress(
1007                 "joe.doe@apache.org",
1008                 "joe.doe@apache.org"));
1009         arrExpected.add(
1010             new InternetAddress(
1011                 "someone_here@work-address.com.au",
1012                 "someone_here@work-address.com.au"));
1013 
1014         for (int i = 0; i < ARR_VALID_EMAILS.length; i++)
1015         {
1016             // set replyTo
1017             this.email.addReplyTo(ARR_VALID_EMAILS[i], testEmailNames[i]);
1018         }
1019 
1020         // retrieve and verify
1021         assertEquals(arrExpected.size(), this.email.getReplyList().size());
1022         assertEquals(
1023             arrExpected.toString(),
1024             this.email.getReplyList().toString());
1025 
1026         // ====================================================================
1027         // Test Exceptions
1028         // ====================================================================
1029         // reset the mail class
1030         MockEmailConcrete anotherEmail = new MockEmailConcrete();
1031 
1032         // bad encoding
1033         try
1034         {
1035             // set a dodgy encoding scheme
1036             anotherEmail.addReplyTo("me@home.com", "me@home.com", "bad.encoding\uc5ec\n");
1037             fail("setting invalid charset should have failed!");
1038         }
1039         catch (IllegalCharsetNameException e)
1040         {
1041             // expected runtime exception.
1042         }
1043     }
1044 
1045     /** */
1046     public void testAddHeader()
1047     {
1048         // ====================================================================
1049         // Test Success
1050         // ====================================================================
1051         Map ht = new Hashtable();
1052         ht.put("X-Priority", "1");
1053         ht.put("Disposition-Notification-To", "me@home.com");
1054         ht.put("X-Mailer", "Sendmail");
1055 
1056         for (Iterator items = ht.entrySet().iterator(); items.hasNext();)
1057         {
1058             Map.Entry entry = (Map.Entry) items.next();
1059             String strName = (String) entry.getKey();
1060             String strValue = (String) entry.getValue();
1061             this.email.addHeader(strName, strValue);
1062         }
1063 
1064         assertEquals(ht.size(), this.email.getHeaders().size());
1065         assertEquals(ht, this.email.getHeaders());
1066     }
1067 
1068     /** */
1069     public void testAddHeaderEx()
1070     {
1071         // ====================================================================
1072         // Test Exceptions
1073         // ====================================================================
1074         Map htBad = new Hashtable();
1075         htBad.put("X-Mailer", "");
1076         htBad.put("X-Priority", "");
1077         htBad.put("", "me@home.com");
1078 
1079         Map arrExpected = new Hashtable();
1080         for (Iterator items = htBad.entrySet().iterator(); items.hasNext();)
1081         {
1082             Map.Entry element = (Map.Entry) items.next();
1083             try
1084             {
1085                 String strName = (String) element.getKey();
1086                 String strValue = (String) element.getValue();
1087 
1088                 this.email.addHeader(strName, strValue);
1089                 fail("Should have thrown an exception");
1090             }
1091             catch (IllegalArgumentException e)
1092             {
1093                 assertTrue(true);
1094             }
1095         }
1096 
1097         assertEquals(arrExpected.size(), this.email.getHeaders().size());
1098         assertEquals(
1099             arrExpected.toString(),
1100             this.email.getHeaders().toString());
1101     }
1102 
1103     /** */
1104     public void testSetHeaders()
1105     {
1106         // ====================================================================
1107         // Test Success
1108         // ====================================================================
1109         Map ht = new Hashtable();
1110         ht.put("X-Priority", "1");
1111         ht.put("Disposition-Notification-To", "me@home.com");
1112         ht.put("X-Mailer", "Sendmail");
1113 
1114         this.email.setHeaders(ht);
1115 
1116         assertEquals(ht.size(), this.email.getHeaders().size());
1117         assertEquals(ht, this.email.getHeaders());
1118     }
1119 
1120     /** */
1121     public void testSetHeadersEx()
1122     {
1123         // ====================================================================
1124         // Test Exceptions
1125         // ====================================================================
1126         // first test
1127         Map htBad = new Hashtable();
1128         htBad.put("X-Mailer", "");
1129 
1130         Map arrExpected = new Hashtable();
1131 
1132         try
1133         {
1134             this.email.setHeaders(htBad);
1135             fail("Should have thrown an exception");
1136         }
1137         catch (IllegalArgumentException e)
1138         {
1139             assertTrue(true);
1140         }
1141 
1142         assertEquals(arrExpected.size(), this.email.getHeaders().size());
1143         assertEquals(
1144             arrExpected.toString(),
1145             this.email.getHeaders().toString());
1146 
1147         // ====================================================================
1148         // second test
1149         htBad = new Hashtable();
1150         htBad.put("", "me@home.com");
1151 
1152         try
1153         {
1154             this.email.setHeaders(htBad);
1155             fail("Should have thrown an exception");
1156         }
1157         catch (IllegalArgumentException e)
1158         {
1159             assertTrue(true);
1160         }
1161 
1162         assertEquals(arrExpected.size(), this.email.getHeaders().size());
1163         assertEquals(
1164             arrExpected.toString(),
1165             this.email.getHeaders().toString());
1166     }
1167 
1168     /** */
1169     public void testSetSubject()
1170     {
1171 
1172         for (int i = 0; i < testCharsValid.length; i++)
1173         {
1174             this.email.setSubject(testCharsValid[i]);
1175             assertEquals(testCharsValid[i], this.email.getSubject());
1176         }
1177     }
1178 
1179     /** */
1180     public void testSendEx()
1181     {
1182         // ====================================================================
1183         // Test Exceptions (in getMailSession)
1184         // ====================================================================
1185         // hostname not set
1186         try
1187         {
1188             this.getMailServer();
1189 
1190             this.email = new MockEmailConcrete();
1191             this.email.send();
1192             fail("Should have thrown an exception");
1193         }
1194         catch (EmailException e)
1195         {
1196             this.fakeMailServer.stop();
1197             assertTrue(true);
1198         }
1199 
1200         // bad hostname
1201         try
1202         {
1203             this.getMailServer();
1204 
1205             this.email = new MockEmailConcrete();
1206             this.email.setSubject("Test Email #1 Subject");
1207             this.email.setHostName("bad.host.com");
1208             this.email.setFrom("me@home.com");
1209             this.email.addTo("me@home.com");
1210             this.email.addCc("me@home.com");
1211             this.email.addBcc("me@home.com");
1212             this.email.addReplyTo("me@home.com");
1213 
1214             this.email.setContent(
1215                 "test string object",
1216                 " ; charset=" + Email.US_ASCII);
1217 
1218             this.email.send();
1219             fail("Should have thrown an exception");
1220         }
1221         catch (EmailException e)
1222         {
1223             assertTrue(e.getCause() instanceof ParseException);
1224             this.fakeMailServer.stop();
1225             assertTrue(true);
1226         }
1227 
1228         // ====================================================================
1229         // Test Exceptions (in send)
1230         // ====================================================================
1231         // from add not set
1232         try
1233         {
1234             this.getMailServer();
1235 
1236             this.email = new MockEmailConcrete();
1237             this.email.setHostName(this.strTestMailServer);
1238             this.email.setSmtpPort(this.getMailServerPort());
1239 
1240             this.email.send();
1241             fail("Should have thrown an exception");
1242         }
1243         catch (EmailException e)
1244         {
1245             this.fakeMailServer.stop();
1246             assertTrue(true);
1247         }
1248 
1249         // destination (to/cc/bcc) dd not set
1250         try
1251         {
1252             this.getMailServer();
1253 
1254             this.email = new MockEmailConcrete();
1255             this.email.setHostName(this.strTestMailServer);
1256             this.email.setSmtpPort(this.getMailServerPort());
1257             this.email.setFrom("me@home.com");
1258             this.email.send();
1259             fail("Should have thrown an exception");
1260         }
1261         catch (EmailException e)
1262         {
1263             this.fakeMailServer.stop();
1264             assertTrue(true);
1265         }
1266 
1267         // bad auth set
1268         try
1269         {
1270             this.getMailServer();
1271 
1272             this.email = new MockEmailConcrete();
1273             this.email.setHostName(this.strTestMailServer);
1274             this.email.setSmtpPort(this.getMailServerPort());
1275             this.email.setFrom(this.strTestMailFrom);
1276             this.email.addTo(this.strTestMailTo);
1277             this.email.setAuthentication(null, null);
1278             this.email.send();
1279             fail("Should have thrown an exception");
1280         }
1281         catch (EmailException e)
1282         {
1283             this.fakeMailServer.stop();
1284             assertTrue(true);
1285         }
1286     }
1287 
1288     /** */
1289     public void testGetSetSentDate()
1290     {
1291         // with input date
1292 
1293         Date dtTest = Calendar.getInstance().getTime();
1294         this.email.setSentDate(dtTest);
1295         assertEquals(dtTest, this.email.getSentDate());
1296 
1297         // with null input (this is a fudge :D)
1298         this.email.setSentDate(null);
1299 
1300         Date sentDate = this.email.getSentDate();
1301 
1302         // Date objects are millisecond specific. If you have a slow processor,
1303         // time passes between the generation of dtTest and the new Date() in
1304         // getSentDate() and this test fails. Make sure that the difference
1305         // is less than a second...
1306         assertTrue(Math.abs(sentDate.getTime() - dtTest.getTime()) < 1000);
1307     }
1308 
1309     /**
1310      * @throws EmailException when there are problems adding an address
1311      * @throws UnsupportedEncodingException on bad email addresses
1312      */
1313     public void testToInternetAddressArray() throws EmailException, UnsupportedEncodingException
1314     {
1315         List testInetEmailValid = new ArrayList();
1316 
1317         testInetEmailValid.add(new InternetAddress("me@home.com", "Name1"));
1318         testInetEmailValid.add(
1319             new InternetAddress(
1320                 "joe.doe@apache.org",
1321                 "joe.doe@apache.org"));
1322         testInetEmailValid.add(
1323             new InternetAddress(
1324                 "someone_here@work-address.com.au",
1325                 "someone_here@work-address.com.au"));
1326 
1327         this.email.setBcc(testInetEmailValid);
1328         assertEquals(
1329             testInetEmailValid.size(),
1330             this.email.toInternetAddressArray(
1331                 this.email.getBccList()).length);
1332     }
1333 
1334     /** */
1335     public void testSetPopBeforeSmtp()
1336     {
1337         // simple test (can be improved)
1338         boolean boolPopBeforeSmtp = true;
1339         String strHost = "mail.home.com";
1340         String strUsername = "user.name";
1341         String strPassword = "user.passwd";
1342 
1343         this.email.setPopBeforeSmtp(
1344             boolPopBeforeSmtp,
1345             strHost,
1346             strUsername,
1347             strPassword);
1348 
1349         // retrieve and verify
1350         assertEquals(boolPopBeforeSmtp, this.email.isPopBeforeSmtp());
1351         assertEquals(strHost, this.email.getPopHost());
1352         assertEquals(strUsername, this.email.getPopUsername());
1353         assertEquals(strPassword, this.email.getPopPassword());
1354     }
1355 
1356     /**
1357      * Test: When Email.setCharset() is called, a subsequent setContent()
1358      * should use that charset for text content types unless overridden
1359      * by the contentType parameter.
1360      * See https://issues.apache.org/jira/browse/EMAIL-1.
1361      *
1362      *
1363      * Case 1:
1364      * Setting a default charset results in adding that charset info to
1365      * to the content type of a text/based content object.
1366      * @throws Exception on any error
1367      */
1368     public void testDefaultCharsetAppliesToTextContent() throws Exception
1369     {
1370         this.email.setHostName(this.strTestMailServer);
1371         this.email.setSmtpPort(this.getMailServerPort());
1372         this.email.setFrom("a@b.com");
1373         this.email.addTo("c@d.com");
1374         this.email.setSubject("test mail");
1375 
1376         this.email.setCharset("ISO-8859-1");
1377         this.email.setContent("test content", "text/plain");
1378         this.email.buildMimeMessage();
1379         MimeMessage msg = this.email.getMimeMessage();
1380         msg.saveChanges();
1381         assertEquals("text/plain; charset=ISO-8859-1", msg.getContentType());
1382     }
1383 
1384     /**
1385      * Case 2:
1386      * A default charset is overridden by an explicitly specified
1387      * charset in setContent().
1388      * @throws Exception on any error
1389      */
1390     public void testDefaultCharsetCanBeOverriddenByContentType()
1391         throws Exception
1392     {
1393         this.email.setHostName(this.strTestMailServer);
1394         this.email.setSmtpPort(this.getMailServerPort());
1395         this.email.setFrom("a@b.com");
1396         this.email.addTo("c@d.com");
1397         this.email.setSubject("test mail");
1398 
1399         this.email.setCharset("ISO-8859-1");
1400         this.email.setContent("test content", "text/plain; charset=US-ASCII");
1401         this.email.buildMimeMessage();
1402         MimeMessage msg = this.email.getMimeMessage();
1403         msg.saveChanges();
1404         assertEquals("text/plain; charset=US-ASCII", msg.getContentType());
1405     }
1406 
1407     /**
1408      * Case 3:
1409      * A non-text content object ignores a default charset entirely.
1410      * @throws Exception on any error
1411      */
1412     public void testDefaultCharsetIgnoredByNonTextContent()
1413         throws Exception
1414     {
1415         this.email.setHostName(this.strTestMailServer);
1416         this.email.setSmtpPort(this.getMailServerPort());
1417         this.email.setFrom("a@b.com");
1418         this.email.addTo("c@d.com");
1419         this.email.setSubject("test mail");
1420 
1421         this.email.setCharset("ISO-8859-1");
1422         this.email.setContent("test content", "application/octet-stream");
1423         this.email.buildMimeMessage();
1424         MimeMessage msg = this.email.getMimeMessage();
1425         msg.saveChanges();
1426         assertEquals("application/octet-stream", msg.getContentType());
1427     }
1428 }