| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.mail; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.URL; |
| import java.util.List; |
| |
| import javax.activation.DataSource; |
| import javax.activation.FileDataSource; |
| import javax.mail.internet.MimeMessage; |
| |
| import org.apache.commons.mail.mocks.MockHtmlEmailConcrete; |
| import org.apache.commons.mail.settings.EmailConfiguration; |
| import org.apache.commons.mail.util.MimeMessageParser; |
| import org.junit.Before; |
| import org.junit.Ignore; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.powermock.core.classloader.annotations.PrepareForTest; |
| import org.powermock.modules.junit4.PowerMockRunner; |
| |
| /** |
| * JUnit test case for HtmlEmail Class. |
| * |
| * @since 1.0 |
| */ |
| @RunWith(PowerMockRunner.class) |
| @PrepareForTest( { MockHtmlEmailConcrete.class }) |
| public class HtmlEmailTest extends AbstractEmailTest |
| { |
| private MockHtmlEmailConcrete email; |
| |
| @Before |
| public void setUpHtmlEmailTest() |
| { |
| // reusable objects to be used across multiple tests |
| this.email = new MockHtmlEmailConcrete(); |
| } |
| |
| @Test |
| public void testGetSetTextMsg() throws EmailException |
| { |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| for (final String validChar : testCharsValid) |
| { |
| this.email.setTextMsg(validChar); |
| assertEquals(validChar, this.email.getTextMsg()); |
| } |
| |
| // ==================================================================== |
| // Test Exception |
| // ==================================================================== |
| for (final String invalidChar : this.testCharsNotValid) |
| { |
| try |
| { |
| this.email.setTextMsg(invalidChar); |
| fail("Should have thrown an exception"); |
| } |
| catch (final EmailException e) |
| { |
| assertTrue(true); |
| } |
| } |
| |
| } |
| |
| @Test |
| public void testGetSetHtmlMsg() throws EmailException |
| { |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| for (final String validChar : testCharsValid) |
| { |
| this.email.setHtmlMsg(validChar); |
| assertEquals(validChar, this.email.getHtmlMsg()); |
| } |
| |
| // ==================================================================== |
| // Test Exception |
| // ==================================================================== |
| for (final String invalidChar : this.testCharsNotValid) |
| { |
| try |
| { |
| this.email.setHtmlMsg(invalidChar); |
| fail("Should have thrown an exception"); |
| } |
| catch (final EmailException e) |
| { |
| assertTrue(true); |
| } |
| } |
| |
| } |
| |
| @Test |
| public void testGetSetMsg() throws EmailException |
| { |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| for (final String validChar : testCharsValid) |
| { |
| this.email.setMsg(validChar); |
| assertEquals(validChar, this.email.getTextMsg()); |
| |
| assertTrue( |
| this.email.getHtmlMsg().contains(validChar)); |
| } |
| |
| // ==================================================================== |
| // Test Exception |
| // ==================================================================== |
| for (final String invalidChar : this.testCharsNotValid) |
| { |
| try |
| { |
| this.email.setMsg(invalidChar); |
| fail("Should have thrown an exception"); |
| } |
| catch (final EmailException e) |
| { |
| assertTrue(true); |
| } |
| } |
| |
| } |
| |
| @Test |
| public void testEmbedUrl() throws Exception |
| { |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| |
| final String strEmbed = |
| this.email.embed(new URL(this.strTestURL), "Test name"); |
| assertNotNull(strEmbed); |
| assertEquals(HtmlEmail.CID_LENGTH, strEmbed.length()); |
| |
| // if we embed the same name again, do we get the same content ID |
| // back? |
| final String testCid = |
| this.email.embed(new URL(this.strTestURL), "Test name"); |
| assertEquals(strEmbed, testCid); |
| |
| // if we embed the same URL under a different name, is the content ID |
| // unique? |
| final String newCid = |
| this.email.embed(new URL(this.strTestURL), "Test name 2"); |
| assertFalse(strEmbed.equals(newCid)); |
| |
| // ==================================================================== |
| // Test Exceptions |
| // ==================================================================== |
| |
| // Does an invalid URL throw an exception? |
| try |
| { |
| this.email.embed(createInvalidURL(), "Bad URL"); |
| fail("Should have thrown an exception"); |
| } |
| catch (final EmailException e) |
| { |
| // expected |
| } |
| |
| // if we try to embed a different URL under a previously used name, |
| // does it complain? |
| try |
| { |
| this.email.embed(new URL("http://www.google.com"), "Test name"); |
| fail("shouldn't be able to use an existing name with a different URL!"); |
| } |
| catch (final EmailException e) |
| { |
| // expected |
| } |
| } |
| |
| @Test |
| public void testEmbedFile() throws Exception |
| { |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| |
| final File file = File.createTempFile("testEmbedFile", "txt"); |
| file.deleteOnExit(); |
| final String strEmbed = this.email.embed(file); |
| assertNotNull(strEmbed); |
| assertEquals("generated CID has wrong length", |
| HtmlEmail.CID_LENGTH, strEmbed.length()); |
| |
| // if we embed the same file again, do we get the same content ID |
| // back? |
| final String testCid = |
| this.email.embed(file); |
| assertEquals("didn't get same CID after embedding same file twice", |
| strEmbed, testCid); |
| |
| // if we embed a new file, is the content ID unique? |
| final File otherFile = File.createTempFile("testEmbedFile2", "txt"); |
| otherFile.deleteOnExit(); |
| final String newCid = this.email.embed(otherFile); |
| assertFalse("didn't get unique CID from embedding new file", |
| strEmbed.equals(newCid)); |
| } |
| |
| @Test |
| public void testEmbedUrlAndFile() throws Exception |
| { |
| final File tmpFile = File.createTempFile("testfile", "txt"); |
| tmpFile.deleteOnExit(); |
| final String fileCid = this.email.embed(tmpFile); |
| |
| final URL fileUrl = tmpFile.toURI().toURL(); |
| final String urlCid = this.email.embed(fileUrl, "urlName"); |
| |
| assertFalse("file and URL cids should be different even for same resource", |
| fileCid.equals(urlCid)); |
| } |
| |
| @Test |
| public void testEmbedDataSource() throws Exception |
| { |
| final File tmpFile = File.createTempFile("testEmbedDataSource", "txt"); |
| tmpFile.deleteOnExit(); |
| final FileDataSource dataSource = new FileDataSource(tmpFile); |
| |
| // does embedding a datasource without a name fail? |
| try |
| { |
| this.email.embed(dataSource, ""); |
| fail("embedding with an empty string for a name should fail"); |
| } |
| catch (final EmailException e) |
| { |
| // expected |
| } |
| |
| // properly embed the datasource |
| final String cid = this.email.embed(dataSource, "testname"); |
| |
| // does embedding the same datasource under the same name return |
| // the original cid? |
| final String sameCid = this.email.embed(dataSource, "testname"); |
| assertEquals("didn't get same CID for embedding same datasource twice", |
| cid, sameCid); |
| |
| // does embedding another datasource under the same name fail? |
| final File anotherFile = File.createTempFile("testEmbedDataSource2", "txt"); |
| anotherFile.deleteOnExit(); |
| final FileDataSource anotherDS = new FileDataSource(anotherFile); |
| try |
| { |
| this.email.embed(anotherDS, "testname"); |
| } |
| catch (final EmailException e) |
| { |
| // expected |
| } |
| } |
| |
| /** |
| * @throws EmailException when bad addresses and attachments are used |
| * @throws IOException if creating a temp file, URL or sending fails |
| */ |
| @Test |
| public void testSend() throws EmailException, IOException |
| { |
| final EmailAttachment attachment = new EmailAttachment(); |
| |
| /** File to used to test file attachments (Must be valid) */ |
| final File testFile = File.createTempFile("commons-email-testfile", ".txt"); |
| testFile.deleteOnExit(); |
| |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| this.getMailServer(); |
| |
| String strSubject = "Test HTML Send #1 Subject (w charset)"; |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.addTo(this.strTestMailTo); |
| |
| /** File to used to test file attachmetns (Must be valid) */ |
| attachment.setName("Test Attachment"); |
| attachment.setDescription("Test Attachment Desc"); |
| attachment.setPath(testFile.getAbsolutePath()); |
| this.email.attach(attachment); |
| |
| //this.email.setAuthentication(this.strTestUser, this.strTestPasswd); |
| |
| this.email.setCharset(EmailConstants.ISO_8859_1); |
| this.email.setSubject(strSubject); |
| |
| final URL url = new URL(EmailConfiguration.TEST_URL); |
| final String cid = this.email.embed(url, "Apache Logo"); |
| |
| final String strHtmlMsg = |
| "<html>The Apache logo - <img src=\"cid:" + cid + "\"><html>"; |
| |
| this.email.setHtmlMsg(strHtmlMsg); |
| this.email.setTextMsg( |
| "Your email client does not support HTML emails"); |
| |
| this.email.send(); |
| this.fakeMailServer.stop(); |
| // validate txt message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getTextMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| true); |
| |
| // validate html message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getHtmlMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| false); |
| |
| // validate attachment |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| attachment.getName(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| false); |
| |
| this.getMailServer(); |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.addTo(this.strTestMailTo); |
| |
| if (this.strTestUser != null && this.strTestPasswd != null) |
| { |
| this.email.setAuthentication( |
| this.strTestUser, |
| this.strTestPasswd); |
| } |
| |
| strSubject = "Test HTML Send #1 Subject (wo charset)"; |
| this.email.setSubject(strSubject); |
| this.email.setTextMsg("Test message"); |
| |
| this.email.send(); |
| this.fakeMailServer.stop(); |
| // validate txt message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getTextMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| true); |
| } |
| |
| @Test |
| public void testSend2() throws Exception |
| { |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| |
| this.getMailServer(); |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.addTo(this.strTestMailTo); |
| |
| if (this.strTestUser != null && this.strTestPasswd != null) |
| { |
| this.email.setAuthentication( |
| this.strTestUser, |
| this.strTestPasswd); |
| } |
| |
| String strSubject = "Test HTML Send #2 Subject (wo charset)"; |
| this.email.setSubject(strSubject); |
| this.email.setMsg("Test txt msg"); |
| |
| this.email.send(); |
| this.fakeMailServer.stop(); |
| // validate txt message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getTextMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| true); |
| |
| // validate html message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getHtmlMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| false); |
| |
| this.getMailServer(); |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.addTo(this.strTestMailTo); |
| |
| if (this.strTestUser != null && this.strTestPasswd != null) |
| { |
| this.email.setAuthentication( |
| this.strTestUser, |
| this.strTestPasswd); |
| } |
| |
| strSubject = "Test HTML Send #2 Subject (w charset)"; |
| this.email.setCharset(EmailConstants.ISO_8859_1); |
| this.email.setSubject(strSubject); |
| this.email.setMsg("Test txt msg"); |
| |
| this.email.send(); |
| this.fakeMailServer.stop(); |
| // validate txt message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getTextMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| true); |
| |
| // validate html message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getHtmlMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| false); |
| |
| } |
| |
| @Test |
| @Ignore |
| public void testSendWithDefaultCharset() throws Exception |
| { |
| // Test is disabled as its result is dependent on the execution order: |
| // the mail.mime.charset property is normally cached by the MimeUtility |
| // class, thus setting it to another value while running the tests |
| // might not have the expected result. |
| |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| |
| System.setProperty(EmailConstants.MAIL_MIME_CHARSET, "iso-8859-15"); |
| |
| this.getMailServer(); |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.addTo(this.strTestMailTo); |
| |
| if (this.strTestUser != null && this.strTestPasswd != null) |
| { |
| this.email.setAuthentication( |
| this.strTestUser, |
| this.strTestPasswd); |
| } |
| |
| final String strSubject = "Test HTML Send Subject (w default charset)"; |
| this.email.setSubject(strSubject); |
| this.email.setMsg("Test txt msg ä"); // add non-ascii character, otherwise us-ascii will be used |
| |
| this.email.send(); |
| this.fakeMailServer.stop(); |
| // validate charset |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| "charset=iso-8859-15", |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| true); |
| |
| System.clearProperty(EmailConstants.MAIL_MIME_CHARSET); |
| |
| } |
| |
| /** |
| * Create a HTML email containing an URL pointing to a ZIP file |
| * to be downloaded. According to EMAIL-93 the resulting URL |
| * "http://paradisedelivery.homeip.net/delivery/?file=TZC268X93337..zip" |
| * contains TWO dots instead of one dot which breaks the link. |
| */ |
| @Test |
| public void testAddZipUrl() throws Exception |
| { |
| final String htmlMsg = |
| "Please click on the following link: <br><br>" + |
| "<a href=\"http://paradisedelivery.homeip.net/delivery/?file=3DTZC268X93337.zip\">" + |
| "http://paradisedelivery.homeip.net/delivery/?file=3DTZC268X93337.zip" + |
| "</a><br><br>Customer satisfaction is very important for us."; |
| |
| this.getMailServer(); |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.addTo(this.strTestMailTo); |
| this.email.setCharset(EmailConstants.ISO_8859_1); |
| |
| if (this.strTestUser != null && this.strTestPasswd != null) |
| { |
| this.email.setAuthentication( |
| this.strTestUser, |
| this.strTestPasswd); |
| } |
| |
| final String strSubject = "A dot (\".\") is appended to some ULRs of a HTML mail."; |
| this.email.setSubject(strSubject); |
| this.email.setHtmlMsg(htmlMsg); |
| |
| this.email.send(); |
| this.fakeMailServer.stop(); |
| |
| // validate html message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getHtmlMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| false); |
| |
| // make sure that no double dots show up |
| assertTrue(this.email.getHtmlMsg().contains("3DTZC268X93337.zip")); |
| assertFalse(this.email.getHtmlMsg().contains("3DTZC268X93337..zip")); |
| } |
| |
| /** |
| * According to EMAIL-95 calling buildMimeMessage() before calling send() |
| * causes duplicate mime parts - now we throw an exception to catch the |
| * problem |
| */ |
| @Test |
| public void testCallingBuildMimeMessageBeforeSent() throws Exception { |
| |
| final String htmlMsg = "<b>Hello World</b>"; |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.addTo(this.strTestMailTo); |
| this.email.setCharset(EmailConstants.ISO_8859_1); |
| |
| if (this.strTestUser != null && this.strTestPasswd != null) |
| { |
| this.email.setAuthentication( |
| this.strTestUser, |
| this.strTestPasswd); |
| } |
| |
| final String strSubject = "testCallingBuildMimeMessageBeforeSent"; |
| this.email.setSubject(strSubject); |
| this.email.setHtmlMsg(htmlMsg); |
| |
| // this should NOT be called when sending a message |
| this.email.buildMimeMessage(); |
| |
| try |
| { |
| this.email.send(); |
| } |
| catch(final IllegalStateException e) |
| { |
| return; |
| } |
| |
| fail("Expecting an exception when calling buildMimeMessage() before send() ..."); |
| } |
| |
| /** |
| * EMAIL-73 - check that providing a plain text content using setMsg() |
| * creates a plain content and HTML content using {@code <pre>} tags. |
| */ |
| @Test |
| public void testSendWithPlainTextButNoHtmlContent() throws EmailException, IOException |
| { |
| this.getMailServer(); |
| |
| final String strSubject = "testSendWithPlainTextButNoHtmlContent"; |
| |
| this.email = new MockHtmlEmailConcrete(); |
| this.email.setHostName(this.strTestMailServer); |
| this.email.setSmtpPort(this.getMailServerPort()); |
| this.email.setFrom(this.strTestMailFrom); |
| this.email.addTo(this.strTestMailTo); |
| this.email.setAuthentication(this.strTestUser, this.strTestPasswd); |
| this.email.setCharset(EmailConstants.ISO_8859_1); |
| this.email.setSubject(strSubject); |
| this.email.setMsg("This is a plain text content : <b><&npsb;></html></b>"); |
| |
| this.email.send(); |
| |
| this.fakeMailServer.stop(); |
| |
| // validate text message |
| validateSend( |
| this.fakeMailServer, |
| strSubject, |
| this.email.getTextMsg(), |
| this.email.getFromAddress(), |
| this.email.getToAddresses(), |
| this.email.getCcAddresses(), |
| this.email.getBccAddresses(), |
| true); |
| } |
| |
| /** |
| * Test that the specified Content-ID is used when embedding a File |
| * object in an HtmlEmail. |
| * |
| * Rolled back the changes since they broke real emails therefore |
| * the test is currently disabled. |
| * |
| * see https://issues.apache.org/jira/browse/EMAIL-101 |
| */ |
| @Test |
| public void testEmbedFileWithCID() throws Exception |
| { |
| // ==================================================================== |
| // Test Success |
| // ==================================================================== |
| |
| final File file = File.createTempFile("testEmbedFile", "txt"); |
| file.deleteOnExit(); |
| |
| final String testCid = "Test CID"; |
| final String encodedCid = EmailUtils.encodeUrl(testCid); |
| |
| // if we embed a new file, do we get the content ID we specified back? |
| final String strEmbed = this.email.embed(file, testCid); |
| assertNotNull(strEmbed); |
| assertEquals("didn't get same CID when embedding with a specified CID", encodedCid, strEmbed); |
| |
| // if we embed the same file again, do we get the same content ID |
| // back? |
| final String returnedCid = this.email.embed(file); |
| assertEquals("didn't get same CID after embedding same file twice", encodedCid, returnedCid); |
| } |
| |
| @Test |
| public void testHtmlMailMimeLayout() throws Exception |
| { |
| assertCorrectContentType("contentTypeTest.gif", "image/gif"); |
| assertCorrectContentType("contentTypeTest.jpg", "image/jpeg"); |
| assertCorrectContentType("contentTypeTest.png", "image/png"); |
| } |
| |
| private void assertCorrectContentType(final String picture, final String contentType) throws Exception { |
| final HtmlEmail htmlEmail = createDefaultHtmlEmail(); |
| final String cid = htmlEmail.embed(new File("./src/test/resources/images/" + picture), "Apache Logo"); |
| final String htmlMsg = "<html><img src=\"cid:" + cid + "\"><html>"; |
| htmlEmail.setHtmlMsg(htmlMsg); |
| htmlEmail.buildMimeMessage(); |
| |
| final MimeMessage mm = htmlEmail.getMimeMessage(); |
| mm.saveChanges(); |
| final MimeMessageParser mmp = new MimeMessageParser(mm); |
| mmp.parse(); |
| |
| final List<?> attachments = mmp.getAttachmentList(); |
| assertEquals("Attachment size", 1, attachments.size()); |
| |
| final DataSource ds = (DataSource) attachments.get(0); |
| assertEquals("Content type", contentType, ds.getContentType()); |
| } |
| |
| private HtmlEmail createDefaultHtmlEmail() throws EmailException { |
| final HtmlEmail htmlEmail = new HtmlEmail(); |
| htmlEmail.setHostName(this.strTestMailServer); |
| htmlEmail.setSmtpPort(this.getMailServerPort()); |
| htmlEmail.setFrom("a@b.com"); |
| htmlEmail.addTo("c@d.com"); |
| return htmlEmail; |
| } |
| } |