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 static org.junit.Assert.*;
20  
21  import org.apache.commons.io.FileUtils;
22  import org.apache.commons.io.IOUtils;
23  import org.apache.commons.mail.resolver.DataSourceClassPathResolver;
24  import org.apache.commons.mail.resolver.DataSourceCompositeResolver;
25  import org.apache.commons.mail.resolver.DataSourceUrlResolver;
26  import org.apache.commons.mail.mocks.MockImageHtmlEmailConcrete;
27  import org.apache.commons.mail.util.MimeMessageParser;
28  import org.apache.commons.mail.util.MimeMessageUtils;
29  import org.junit.Before;
30  import org.junit.Test;
31  
32  import javax.mail.internet.MimeMessage;
33  import java.io.File;
34  import java.io.IOException;
35  import java.io.InputStream;
36  import java.net.URL;
37  import java.util.List;
38  import java.util.logging.Level;
39  import java.util.logging.Logger;
40  import java.util.regex.Matcher;
41  import java.util.regex.Pattern;
42  
43  public class ImageHtmlEmailTest extends HtmlEmailTest {
44  
45      private static final boolean TEST_IS_LENIENT = true;
46      private static final URL TEST_IMAGE_URL = ImageHtmlEmailTest.class.getResource("/images/asf_logo_wide.gif");
47      private static final File TEST_IMAGE_DIR = new File(TEST_IMAGE_URL.getPath()).getParentFile();
48      private static final URL TEST_HTML_URL = ImageHtmlEmailTest.class.getResource("/attachments/download_email.cgi.html");
49      private static final URL TEST2_HTML_URL = ImageHtmlEmailTest.class.getResource("/attachments/classpathtest.html");
50  
51      private MockImageHtmlEmailConcrete email;
52  
53      @Before
54      public void setupImageHtmlEmailTest() {
55          // reusable objects to be used across multiple tests
56          email = new MockImageHtmlEmailConcrete();
57      }
58  
59      // ======================================================================
60      // Start of Tests
61      // ======================================================================
62  
63      @Test
64      public void testSendHtml() throws Exception {
65  
66          Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
67  
68          // Create the email message
69          getMailServer();
70  
71          String strSubject = "Test HTML Send default";
72  
73          email = new MockImageHtmlEmailConcrete();
74          email.setDataSourceResolver(new DataSourceUrlResolver(TEST_IMAGE_DIR.toURI().toURL(), TEST_IS_LENIENT));
75          email.setHostName(strTestMailServer);
76          email.setSmtpPort(getMailServerPort());
77          email.setFrom(strTestMailFrom);
78          email.addTo(strTestMailTo);
79          email.setSubject(strSubject);
80  
81          String html = loadUrlContent(TEST_HTML_URL);
82  
83          // set the html message
84          email.setHtmlMsg(html);
85  
86          // set the alternative message
87          email.setTextMsg("Your email client does not support HTML messages");
88  
89          // send the email
90          email.send();
91  
92          fakeMailServer.stop();
93  
94          assertEquals(1, fakeMailServer.getMessages().size());
95          MimeMessage mimeMessage = fakeMailServer.getMessages().get(0).getMimeMessage();
96  
97          MimeMessageParser mimeMessageParser = new MimeMessageParser(mimeMessage).parse();
98          assertTrue(mimeMessageParser.getHtmlContent().contains("\"cid:"));
99          assertTrue(mimeMessageParser.getAttachmentList().size() == 3);
100     }
101 
102     @Test
103     public void testSendEmptyHTML() throws Exception {
104         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
105 
106         // Create the email message
107         ImageHtmlEmail email = new ImageHtmlEmail();
108 
109         // set the html message
110         try {
111             email.setHtmlMsg(null);
112             fail("Should fail here!");
113         } catch (EmailException e) {
114             assertTrue(e.getMessage(), e.getMessage().contains("Invalid message supplied"));
115         }
116     }
117 
118     @Test
119     public void testSendEmptyHTML2() throws Exception {
120         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
121 
122         // Create the email message
123         ImageHtmlEmail email = new ImageHtmlEmail();
124 
125         // set the html message
126         try {
127             email.setHtmlMsg("");
128             fail("Should fail here!");
129         } catch (EmailException e) {
130             assertTrue(e.getMessage(), e.getMessage().contains("Invalid message supplied"));
131         }
132 
133     }
134 
135     @Test
136     public void testSendHtmlUrl() throws Exception {
137         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
138 
139         getMailServer();
140 
141         String strSubject = "Test HTML Send default with URL";
142 
143         // Create the email message
144         email = new MockImageHtmlEmailConcrete();
145         email.setHostName(strTestMailServer);
146         email.setSmtpPort(getMailServerPort());
147         email.setFrom(strTestMailFrom);
148         email.addTo(strTestMailTo);
149         email.setSubject(strSubject);
150         email.setDataSourceResolver(new DataSourceUrlResolver(TEST_IMAGE_DIR.toURI().toURL(), TEST_IS_LENIENT));
151 
152         // set the html message
153         email.setHtmlMsg(
154                 "<html><body><img src=\"http://www.apache.org/images/feather.gif\"/></body></html>"
155         );
156 
157         // send the email
158         email.send();
159 
160         fakeMailServer.stop();
161         // validate txt message
162         validateSend(fakeMailServer, strSubject, email.getHtmlMsg(),
163                 email.getFromAddress(), email.getToAddresses(),
164                 email.getCcAddresses(), email.getBccAddresses(), true);
165     }
166 
167     @Test
168     public void testSendHTMLAbsoluteLocalFile() throws Exception {
169         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
170 
171         // Create the email message
172         getMailServer();
173 
174         String strSubject = "Test HTML Send default with absolute local path";
175 
176         // Create the email message
177         email = new MockImageHtmlEmailConcrete();
178         email.setHostName(strTestMailServer);
179         email.setSmtpPort(getMailServerPort());
180         email.setFrom(strTestMailFrom);
181         email.addTo(strTestMailTo);
182         email.setSubject(strSubject);
183         email.setDataSourceResolver(new DataSourceUrlResolver(TEST_IMAGE_DIR.toURI().toURL(), TEST_IS_LENIENT));
184 
185         File file = File.createTempFile("emailtest", ".tst");
186         FileUtils.writeStringToFile(file,
187                 "just some silly data that we won't be able to display anyway");
188 
189         // set the html message
190         email.setHtmlMsg("<html><body><img src=\"" + file.getAbsolutePath()
191                 + "\"/></body></html>"
192         );
193 
194         // send the email
195         email.send();
196 
197         fakeMailServer.stop();
198         // validate txt message
199         validateSend(fakeMailServer, strSubject, email.getHtmlMsg(),
200                 email.getFromAddress(), email.getToAddresses(),
201                 email.getCcAddresses(), email.getBccAddresses(), true);
202     }
203 
204     @Test
205     public void testSendHTMLClassPathFile() throws Exception {
206         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
207 
208         // Create the email message
209         getMailServer();
210 
211         String strSubject = "Test HTML Send default";
212 
213         email = new MockImageHtmlEmailConcrete();
214         email.setDataSourceResolver(new DataSourceClassPathResolver("/", TEST_IS_LENIENT));
215         email.setHostName(strTestMailServer);
216         email.setSmtpPort(getMailServerPort());
217         email.setFrom(strTestMailFrom);
218         email.addTo(strTestMailTo);
219         email.setSubject(strSubject);
220 
221         String html = loadUrlContent(TEST2_HTML_URL);
222 
223         // set the html message
224         email.setHtmlMsg(html);
225 
226         // set the alternative message
227         email.setTextMsg("Your email client does not support HTML messages");
228 
229         // send the email
230         email.send();
231 
232         fakeMailServer.stop();
233 
234         assertEquals(1, fakeMailServer.getMessages().size());
235         MimeMessage mimeMessage = fakeMailServer.getMessages().get(0).getMimeMessage();
236         MimeMessageUtils.writeMimeMessage(mimeMessage, new File("./target/test-emails/testSendHTMLClassPathFile.eml"));
237 
238         MimeMessageParser mimeMessageParser = new MimeMessageParser(mimeMessage).parse();
239         assertTrue(mimeMessageParser.getHtmlContent().contains("\"cid:"));
240         assertTrue(mimeMessageParser.getAttachmentList().size() == 1);
241     }
242 
243     @Test
244     public void testSendHTMLAutoResolveFile() throws Exception {
245         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
246 
247         // Create the email message
248         getMailServer();
249 
250         String strSubject = "Test HTML Send default";
251 
252         email = new MockImageHtmlEmailConcrete();
253         DataSourceResolver dataSourceResolvers[] = new DataSourceResolver[2];
254         dataSourceResolvers[0] = new DataSourceUrlResolver(new URL("http://foo"), true);
255         dataSourceResolvers[1] = new DataSourceClassPathResolver("/", true);
256 
257         email.setDataSourceResolver(new DataSourceCompositeResolver(dataSourceResolvers));
258         email.setHostName(strTestMailServer);
259         email.setSmtpPort(getMailServerPort());
260         email.setFrom(strTestMailFrom);
261         email.addTo(strTestMailTo);
262         email.setSubject(strSubject);
263 
264         String html = loadUrlContent(TEST2_HTML_URL);
265 
266         // set the html message
267         email.setHtmlMsg(html);
268 
269         // set the alternative message
270         email.setTextMsg("Your email client does not support HTML messages");
271 
272         // send the email
273         email.send();
274 
275         fakeMailServer.stop();
276 
277         assertEquals(1, fakeMailServer.getMessages().size());
278         MimeMessage mimeMessage = fakeMailServer.getMessages().get(0).getMimeMessage();
279         MimeMessageUtils.writeMimeMessage(mimeMessage, new File("./target/test-emails/testSendHTMLAutoFile.eml"));
280 
281         MimeMessageParser mimeMessageParser = new MimeMessageParser(mimeMessage).parse();
282         assertTrue(mimeMessageParser.getHtmlContent().contains("\"cid:"));
283         assertTrue(mimeMessageParser.getAttachmentList().size() == 1);
284     }
285 
286     @Test
287     public void testSendHTMLAutoResolveMultipleFiles() throws Exception {
288         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
289 
290         // Create the email message
291         getMailServer();
292 
293         String strSubject = "Test HTML Send default";
294 
295         email = new MockImageHtmlEmailConcrete();
296         DataSourceResolver dataSourceResolver = new DataSourceClassPathResolver("/", true);
297 
298         email.setDataSourceResolver(dataSourceResolver);
299         email.setHostName(strTestMailServer);
300         email.setSmtpPort(getMailServerPort());
301         email.setFrom(strTestMailFrom);
302         email.addTo(strTestMailTo);
303         email.setSubject(strSubject);
304 
305         String html = "<p>First image  <img src=\"images/contentTypeTest.gif\"/></p>" +
306                       "<p>Second image <img src=\"images/contentTypeTest.jpg\"/></p>" +
307                       "<p>Third image  <img src=\"images/contentTypeTest.png\"/></p>";
308 
309         // set the html message
310         email.setHtmlMsg(html);
311 
312         // set the alternative message
313         email.setTextMsg("Your email client does not support HTML messages");
314 
315         // send the email
316         email.send();
317 
318         fakeMailServer.stop();
319 
320         assertEquals(1, fakeMailServer.getMessages().size());
321         MimeMessage mimeMessage = fakeMailServer.getMessages().get(0).getMimeMessage();
322         MimeMessageUtils.writeMimeMessage(mimeMessage, new File("./target/test-emails/testSendHTMLAutoMultipleFiles.eml"));
323 
324         MimeMessageParser mimeMessageParser = new MimeMessageParser(mimeMessage).parse();
325         assertTrue(mimeMessageParser.getHtmlContent().contains("\"cid:"));
326         assertTrue(mimeMessageParser.getAttachmentList().size() == 3);
327     }
328 
329     @Test
330     public void testRegex() {
331         Pattern pattern = Pattern.compile(ImageHtmlEmail.REGEX_IMG_SRC);
332 
333         // ensure that the regex that we use is catching the cases correctly
334         Matcher matcher = pattern
335                 .matcher("<html><body><img src=\"h\"/></body></html>");
336         assertTrue(matcher.find());
337         assertEquals("h", matcher.group(2));
338 
339         matcher = pattern
340                 .matcher("<html><body><img id=\"laskdasdkj\" src=\"h\"/></body></html>");
341         assertTrue(matcher.find());
342         assertEquals("h", matcher.group(2));
343 
344         // uppercase
345         matcher = pattern
346                 .matcher("<html><body><IMG id=\"laskdasdkj\" SRC=\"h\"/></body></html>");
347         assertTrue(matcher.find());
348         assertEquals("h", matcher.group(2));
349 
350         // matches twice
351         matcher = pattern
352                 .matcher("<html><body><img id=\"laskdasdkj\" src=\"http://dstadler1.org/\"/><img id=\"laskdasdkj\" src=\"http://dstadler2.org/\"/></body></html>");
353         assertTrue(matcher.find());
354         assertEquals("http://dstadler1.org/", matcher.group(2));
355         assertTrue(matcher.find());
356         assertEquals("http://dstadler2.org/", matcher.group(2));
357 
358         // what about newlines
359         matcher = pattern
360                 .matcher("<html><body><img\n \rid=\"laskdasdkj\"\n \rsrc=\"http://dstadler1.org/\"/><img id=\"laskdasdkj\" src=\"http://dstadler2.org/\"/></body></html>");
361         assertTrue(matcher.find());
362         assertEquals("http://dstadler1.org/", matcher.group(2));
363         assertTrue(matcher.find());
364         assertEquals("http://dstadler2.org/", matcher.group(2));
365 
366         // what about newlines and other whitespaces
367         matcher = pattern
368                 .matcher("<html><body><img\n \t\rid=\"laskdasdkj\"\n \rsrc \n =\r  \"http://dstadler1.org/\"/><img  \r  id=\" laskdasdkj\"    src    =   \"http://dstadler2.org/\"/></body></html>");
369         assertTrue(matcher.find());
370         assertEquals("http://dstadler1.org/", matcher.group(2));
371         assertTrue(matcher.find());
372         assertEquals("http://dstadler2.org/", matcher.group(2));
373 
374         // what about some real markup
375         matcher = pattern.matcher("<img alt=\"Chart?ck=xradar&amp;w=120&amp;h=120&amp;c=7fff00|7fff00&amp;m=4&amp;g=0\" src=\"/chart?ck=xradar&amp;w=120&amp;h=120&amp;c=7fff00|7fff00&amp;m=4&amp;g=0.2&amp;l=A,C,S,T&amp;v=3.0,3.0,2.0,2.0\"");
376         assertTrue(matcher.find());
377         assertEquals("/chart?ck=xradar&amp;w=120&amp;h=120&amp;c=7fff00|7fff00&amp;m=4&amp;g=0.2&amp;l=A,C,S,T&amp;v=3.0,3.0,2.0,2.0", matcher.group(2));
378 
379         // had a problem with multiple img-source tags
380         matcher = pattern
381                 .matcher("<img src=\"file1\"/><img src=\"file2\"/>");
382         assertTrue(matcher.find());
383         assertEquals("file1", matcher.group(2));
384         assertTrue(matcher.find());
385         assertEquals("file2", matcher.group(2));
386 
387         matcher = pattern
388                 .matcher("<img src=\"file1\"/><img src=\"file2\"/><img src=\"file3\"/><img src=\"file4\"/><img src=\"file5\"/>");
389         assertTrue(matcher.find());
390         assertEquals("file1", matcher.group(2));
391         assertTrue(matcher.find());
392         assertEquals("file2", matcher.group(2));
393         assertTrue(matcher.find());
394         assertEquals("file3", matcher.group(2));
395         assertTrue(matcher.find());
396         assertEquals("file4", matcher.group(2));
397         assertTrue(matcher.find());
398         assertEquals("file5", matcher.group(2));
399 
400         // try with invalid HTML that is seems sometimes, i.e. without closing "/" or "</img>"
401         matcher = pattern.matcher("<img src=\"file1\"><img src=\"file2\">");
402         assertTrue(matcher.find());
403         assertEquals("file1", matcher.group(2));
404         assertTrue(matcher.find());
405         assertEquals("file2", matcher.group(2));
406     }
407 
408     @Test
409     public void testEmail127() throws Exception {
410         Logger.getLogger(ImageHtmlEmail.class.getName()).setLevel(Level.FINEST);
411 
412         getMailServer();
413 
414         String strSubject = "Test HTML Send default with URL";
415 
416         // Create the email message
417         email = new MockImageHtmlEmailConcrete();
418         email.setHostName(strTestMailServer);
419         email.setSmtpPort(getMailServerPort());
420         email.setFrom(strTestMailFrom);
421         email.addTo(strTestMailTo);
422         email.setSubject(strSubject);
423         email.setDataSourceResolver(new DataSourceUrlResolver(TEST_IMAGE_DIR.toURI().toURL(), TEST_IS_LENIENT));
424 
425         // set the html message
426         email.setHtmlMsg("<html><body><img title=\"$\" src=\"http://www.apache.org/images/feather.gif\"/></body></html>");
427 
428         // send the email
429         email.send();
430 
431         fakeMailServer.stop();
432         // validate txt message
433         validateSend(fakeMailServer, strSubject, email.getHtmlMsg(),
434                      email.getFromAddress(), email.getToAddresses(),
435                      email.getCcAddresses(), email.getBccAddresses(), true);
436     }
437     
438     private String loadUrlContent(URL url) throws IOException {
439         InputStream stream = url.openStream();
440         StringBuilder html = new StringBuilder();
441         try {
442             List<String> lines = IOUtils.readLines(stream);
443             for (String line : lines) {
444                 html.append(line).append("\n");
445             }
446         } finally {
447             stream.close();
448         }
449         return html.toString();
450     }
451 }