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.mail;
18  
19  import org.apache.commons.io.FileUtils;
20  import org.apache.commons.io.IOUtils;
21  import org.apache.commons.mail.resolver.DataSourceUrlResolver;
22  import org.apache.commons.mail.settings.EmailConfiguration;
23  import org.junit.Before;
24  import org.junit.Test;
25  
26  import javax.activation.DataSource;
27  import javax.activation.URLDataSource;
28  import javax.mail.Session;
29  import javax.mail.Transport;
30  import javax.mail.internet.MimeMessage;
31  import java.io.ByteArrayOutputStream;
32  import java.io.File;
33  import java.net.URL;
34  import java.util.ArrayList;
35  import java.util.List;
36  
37  /**
38   * This are regression test sending REAL email to REAL mail
39   * servers using REAL recipients.
40   *
41   * The intention is to field-test certain aspects
42   * of email using a variety of mail clients since I'm not a mockist
43   * (see http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting).
44   */
45  public class EmailLiveTest extends AbstractEmailTest
46  {
47      @Before
48      public void setUpLiveTest()
49      {
50          // enforce a default charset UTF-8 otherwise non-ASCII attachment names will not work 
51          System.setProperty("mail.mime.charset", "utf-8");
52  
53          // enforce encoding of non-ASCII characters (violating the MIME specification - see
54          // http://java.sun.com/products/javamail/javadocs/javax/mail/internet/package-summary.html
55          System.setProperty("mail.mime.encodefilename", "true");
56      }
57  
58      protected Email send(Email email) throws EmailException {
59  
60          if( EmailConfiguration.MAIL_FORCE_SEND ) {
61              email.send();
62          }
63          else {
64              email.buildMimeMessage();
65          }
66  
67          return email;
68      }
69  
70      protected String getFromUrl(URL url) throws Exception {
71  
72          URLDataSource dataSource = new URLDataSource(url);
73          ByteArrayOutputStream baos = new ByteArrayOutputStream();
74          IOUtils.copy(dataSource.getInputStream(), baos);
75          return new String(baos.toByteArray(), "UTF-8");
76      }
77  
78      /**
79       * Factory method to create a pre-configured email instance.
80       *
81       * @param clazz the requested implementation class
82       * @return the new instance
83       * @throws Exception creating the Email instance failed
84       */
85      private Email create(Class<? extends Email> clazz) throws Exception {
86  
87          Email email = clazz.newInstance();
88  
89          email.setStartTLSEnabled(EmailConfiguration.MAIL_USE_STARTTLS);
90          email.setStartTLSRequired(EmailConfiguration.MAIL_STARTTLS_REQUIRED);
91          email.setSSLOnConnect(EmailConfiguration.MAIL_USE_SSL);
92          email.setSSLCheckServerIdentity(EmailConfiguration.MAIL_SSL_CHECKSERVERIDENTITY);
93          email.setHostName(EmailConfiguration.MAIL_SERVER);
94          email.setSmtpPort(EmailConfiguration.MAIL_SERVER_PORT);
95          email.setBounceAddress(EmailConfiguration.TEST_FROM);
96          email.setDebug(EmailConfiguration.MAIL_DEBUG);
97          email.setCharset(EmailConfiguration.MAIL_CHARSET);        
98          email.setFrom(EmailConfiguration.TEST_FROM);
99          email.addTo(EmailConfiguration.TEST_TO);
100 
101         if(EmailConfiguration.TEST_USER != null) {
102             email.setAuthenticator(new DefaultAuthenticator(EmailConfiguration.TEST_USER, EmailConfiguration.TEST_PASSWD));
103         }
104 
105         return email;
106     }
107 
108     // ======================================================================
109     // Start of Tests
110     // ======================================================================
111 
112     /**
113      * A sanity check that a simple email also works in reality.
114      *
115      * @throws Exception the test failed
116      */
117     @Test
118     public void testSimpleEmail() throws Exception
119     {
120         SimpleEmail email = (SimpleEmail) create(SimpleEmail.class);
121         email.setSubject("TestSimpleMail");
122         email.setMsg("This is a test mail ... :-)");
123 
124         EmailUtils.writeMimeMessage( new File("./target/test-emails/simplemail.eml"), send(email).getMimeMessage());
125     }
126 
127     /**
128      * A sanity check that a header folding works correctly.
129      *
130      * @throws Exception the test failed
131      */
132     @Test
133     public void testFoldedHeaderValue() throws Exception
134     {
135         SimpleEmail email = (SimpleEmail) create(SimpleEmail.class);
136         email.setSubject("TestFoldedHeaderMail");
137         email.setMsg("This is a test mail with a folded header value... :-)");
138         email.addHeader("X-TestHeader", "This is a very long header value which should be folded into two lines, hopefully");
139 
140         EmailUtils.writeMimeMessage( new File("./target/test-emails/foldedheader.eml"), send(email).getMimeMessage());
141     }
142 
143     /**
144      * A sanity check that a simple email also works in reality.
145      *
146      * @throws Exception the test failed
147      */
148     @Test
149     public void testMultiPartEmail() throws Exception
150     {
151         MultiPartEmail email = (MultiPartEmail) create(MultiPartEmail.class);
152         email.setSubject("TestMultiPartMail");
153         email.setMsg("This is a test mail ... :-)");
154         email.attach(new File("./src/test/resources/attachments/logo.pdf"));
155 
156         EmailUtils.writeMimeMessage( new File("./target/test-emails/multipart.eml"), send(email).getMimeMessage());
157     }
158     
159     /**
160      * This test checks the various options of building a HTML email.
161      *
162      * https://issues.apache.org/jira/browse/EMAIL-65
163      *
164      * @throws Exception the test failed
165      */
166     @Test    
167     public void testHtmlMailMimeLayout() throws Exception
168     {
169         String textMsg;
170         String htmlMsg;
171 
172         // prepare attachments
173 
174         String cid;
175 
176         URL url = new URL(EmailConfiguration.TEST_URL);
177         File imageFile = new File("./src/test/resources/images/asf_logo_wide.gif");
178 
179         EmailAttachment attachment = new EmailAttachment();
180         File attachmentFile = new File("./src/test/resources/attachments/logo.pdf");
181         attachment.setName("logo.pdf");
182         attachment.setDescription("The official Apache logo");
183         attachment.setPath(attachmentFile.getAbsolutePath());
184 
185         // 1) text + html content
186 
187         HtmlEmail htmlEmail1 = (HtmlEmail) create(HtmlEmail.class);
188         textMsg = "Your email client does not support HTML messages";
189         htmlMsg = "<html><b>This is a HTML message without any image</b><html>";
190 
191         htmlEmail1.setSubject( "[email] 1.Test: text + html content");
192         htmlEmail1.setTextMsg(textMsg);
193         htmlEmail1.setHtmlMsg(htmlMsg);
194 
195         EmailUtils.writeMimeMessage( new File("./target/test-emails/htmlemai12.eml"), send(htmlEmail1).getMimeMessage());
196 
197         // 2) text + html content + image as attachment
198 
199         HtmlEmail htmlEmail2 = (HtmlEmail) create(HtmlEmail.class);
200         textMsg = "Your email client does not support HTML messages";
201         htmlMsg = "<html><b>This is a HTML message with an image attachment</b><html>";
202 
203         htmlEmail2.setSubject( "[email] 2.Test: text + html content + image as attachment");
204         htmlEmail2.setTextMsg(textMsg);
205         htmlEmail2.setHtmlMsg(htmlMsg);
206         htmlEmail2.attach(url, "Apache Logo", "The official Apache logo" );
207 
208         EmailUtils.writeMimeMessage( new File("./target/test-emails/htmlemail2.eml"), send(htmlEmail2).getMimeMessage());
209 
210         // 3) text + html content + inline image
211 
212         HtmlEmail htmlEmail3 = (HtmlEmail) create(HtmlEmail.class);
213         textMsg = "Your email client does not support HTML messages";
214         cid = htmlEmail3.embed(imageFile, "Apache Logo");
215 
216         htmlMsg = "<html><b>This is a HTML message with an inline image - <img src=\"cid:"
217             + cid + "\"> and NO attachment</b><html>";
218 
219         htmlEmail3.setSubject( "[email] 3.Test: text + html content + inline image");
220         htmlEmail3.setTextMsg(textMsg);
221         htmlEmail3.setHtmlMsg(htmlMsg);
222 
223         EmailUtils.writeMimeMessage( new File("./target/test-emails/htmlemail3.eml"), send(htmlEmail3).getMimeMessage());
224 
225         // 4) text + html content + inline image + attachment
226 
227         HtmlEmail htmlEmail4 = (HtmlEmail) create(HtmlEmail.class);
228         textMsg = "Your email client does not support HTML messages";
229         cid = htmlEmail4.embed(imageFile, "Apache Logo");
230         htmlMsg = "<html><b>This is a HTML message with an inline image - <img src=\"cid:" + cid + "\"> and attachment</b><html>";
231 
232         htmlEmail4.setSubject( "[email] 4.Test: text + html content + inline image + attachment");
233         htmlEmail4.setTextMsg(textMsg);
234         htmlEmail4.setHtmlMsg(htmlMsg);
235         htmlEmail4.attach(attachment);
236 
237         EmailUtils.writeMimeMessage( new File("./target/test-emails/htmlemail4.eml"), send(htmlEmail4).getMimeMessage());        
238     }
239 
240     /**
241      * This test checks the correct character encoding when sending
242      * non-ASCII content using SimpleEmail.
243      *
244      * https://issues.apache.org/jira/browse/EMAIL-79
245      *
246      * @throws Exception the test failed
247      */
248     @Test    
249     public void testCorrectCharacterEncoding() throws Exception
250     {
251         // U+03B1 : GREEK SMALL LETTER ALPHA
252         // U+03B2 : GREEK SMALL LETTER BETA
253         // U+03B3 : GREEK SMALL LETTER GAMMA
254 
255         final String subject = "[email] 5.Test: Subject with three greek UTF-8 characters : \u03B1\u03B2\u03B3";
256         final String textMsg = "My test body with with three greek UTF-8 characters : \u03B1\u03B2\u03B3\n";
257         final String attachmentName = "\u03B1\u03B2\u03B3.txt";
258 
259         // make sure to set the charset before adding the message content
260         MultiPartEmail email = (MultiPartEmail) create(MultiPartEmail.class);
261         email.setSubject(subject);
262         email.setMsg(textMsg);
263 
264         // create a proper UTF-8 sequence for the text attachment (matching our default charset)
265         DataSource attachment = new javax.mail.util.ByteArrayDataSource(textMsg.getBytes("utf-8"), "text/plain");
266         email.attach(attachment, attachmentName, "Attachment in Greek");
267         
268         EmailUtils.writeMimeMessage( new File("./target/test-emails/correct-encoding.eml"), send(email).getMimeMessage());
269     }
270 
271     /**
272      * Test sending a image HTML mail bases on a local HTML page and local image.
273      *
274      * @throws Exception the test failed                               
275      */
276     @Test    
277     public void testImageHtmlEmailLocal() throws Exception
278     {
279         // use a simple HTML page with one image 
280 
281         File htmlFile = new File("./src/test/resources/html/www.apache.org.html");
282         String htmlMsg1 = FileUtils.readFileToString(htmlFile);
283 
284         ImageHtmlEmail email = (ImageHtmlEmail) create(ImageHtmlEmail.class);
285         email.setDataSourceResolver(new DataSourceUrlResolver(htmlFile.getParentFile().toURI().toURL(), false));
286         email.setSubject("[testImageHtmlEmail] 1.Test: simple html content");
287         email.setHtmlMsg(htmlMsg1);
288 
289         EmailUtils.writeMimeMessage( new File("./target/test-emails/testImageHtmlEmailLocal.eml"), send(email).getMimeMessage());
290     }
291 
292     /**
293      * Test sending a image HTML mail based on a real world website. We
294      * would expect to see the ApacheCon logo at the bottom of the email.
295      * Please note that not all major email clients can display the email
296      * properly.
297      *
298      * @throws Exception the test failed
299      */
300     @Test    
301     public void testImageHtmlEmailRemote() throws Exception
302     {
303         if(EmailConfiguration.MAIL_FORCE_SEND)
304         {
305             URL url = new URL("http://commons.apache.org/email/");
306             // URL url = new URL("http://www.dzone.com/links/index.html");
307             String htmlMsg = getFromUrl(url);
308 
309             ImageHtmlEmail email = (ImageHtmlEmail) create(ImageHtmlEmail.class);
310             email.setDataSourceResolver(new DataSourceUrlResolver(url, true));
311             email.setSubject("[testImageHtmlEmail] 2.Test: complex html content");
312             email.setHtmlMsg(htmlMsg);
313 
314             EmailUtils.writeMimeMessage( new File("./target/test-emails/testImageHtmlEmailRemote.eml"), send(email).getMimeMessage());
315         }
316     }
317 
318     /**
319      * Testing if we are able to send a few emails in a batch, i.e.
320      * using a single authenticated <code>Transport</code> instance.
321      * Use a single instance speeds up processing since the
322      * authorization is only done once.
323      *
324      * https://issues.apache.org/jira/browse/EMAIL-72
325      *
326      * @throws Exception the test failed.
327      */
328     @Test    
329     public void testSendingEmailsInBatch() throws Exception
330     {
331         List<SimpleEmail> emails = new ArrayList<SimpleEmail>();
332 
333         // we need to instantiate an email to provide the mail session - a bit ugly
334         Session session = create(SimpleEmail.class).getMailSession();
335         Transport transport = session.getTransport();
336 
337         // simulate creating a bunch of emails using an existing mail session
338         for(int i=0; i<3; i++)
339         {
340             SimpleEmail personalizedEmail = (SimpleEmail) create(SimpleEmail.class);
341             personalizedEmail.setMailSession(session);
342             personalizedEmail.setSubject("Personalized Test Mail Nr. " + i);
343             personalizedEmail.setMsg("This is a personalized test mail ... :-)");
344             personalizedEmail.buildMimeMessage();
345             emails.add(personalizedEmail);
346         }
347 
348         // send the list of emails using a single 'Transport' instance.
349         if( EmailConfiguration.MAIL_FORCE_SEND )
350         {
351             transport.connect();
352 
353             for (SimpleEmail personalizedEmail : emails)
354             {
355                 MimeMessage mimeMessage = personalizedEmail.getMimeMessage();
356                 Transport.send(mimeMessage);
357                 System.out.println("Successfully sent the following email : " + mimeMessage.getMessageID());
358             }
359 
360             transport.close();
361          }
362     }
363     
364     /**
365      * Testing if we are able to send a partial email with an invalid address.
366      *
367      * https://issues.apache.org/jira/browse/EMAIL-132
368      *
369      * @throws Exception the test failed.
370      */
371     @Test
372     public void testPartialSend() throws Exception
373     {
374         SimpleEmail email = (SimpleEmail) create(SimpleEmail.class);
375         email.addTo("tn@apache.org");
376         email.addTo("asdkljfakld@kadjfka.com");
377         email.setSubject("TestPartialMail");
378         email.setMsg("This is a test mail ... :-)");
379 
380         email.setSendPartial(true);
381 
382         EmailUtils.writeMimeMessage( new File("./target/test-emails/partialmail.eml"), send(email).getMimeMessage());
383     }
384 
385 }