You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2020/12/21 07:29:34 UTC

[james-project] 09/17: JAMES-3431 DSNBounceTest: organize tests in nested classes

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit ec5ac032cc4aeab5ff3fc8dcd9788b69a55a5ba5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Dec 17 09:07:22 2020 +0700

    JAMES-3431 DSNBounceTest: organize tests in nested classes
---
 .../james/transport/mailets/DSNBounceTest.java     | 728 +++++++++++----------
 1 file changed, 368 insertions(+), 360 deletions(-)

diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
index 62e0628..6faa417 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/DSNBounceTest.java
@@ -54,6 +54,7 @@ import org.apache.mailet.base.test.FakeMailContext;
 import org.apache.mailet.base.test.FakeMailContext.SentMail;
 import org.apache.mailet.base.test.FakeMailetConfig;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 
 public class DSNBounceTest {
@@ -80,381 +81,324 @@ public class DSNBounceTest {
             .thenReturn("myhost");
     }
 
-    @Test
-    void getMailetInfoShouldReturnValue() {
-        assertThat(dsnBounce.getMailetInfo()).isEqualTo("DSNBounce Mailet");
-    }
-
-    @Test
-    void getAllowedInitParametersShouldReturnTheParameters() {
-        assertThat(dsnBounce.getAllowedInitParameters()).containsOnly("debug", "passThrough", "messageString", "attachment", "sender", "prefix", "action");
-    }
-
-    @Test
-    void initShouldFailWhenUnknownParameterIsConfigured() {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+    @Nested
+    class Configuration {
+        @Test
+        void getMailetInfoShouldReturnValue() {
+            assertThat(dsnBounce.getMailetInfo()).isEqualTo("DSNBounce Mailet");
+        }
+
+        @Test
+        void getAllowedInitParametersShouldReturnTheParameters() {
+            assertThat(dsnBounce.getAllowedInitParameters()).containsOnly("debug", "passThrough", "messageString", "attachment", "sender", "prefix", "action");
+        }
+
+        @Test
+        void initShouldFailWhenUnknownParameterIsConfigured() {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
                 .setProperty("unknwon", "value")
                 .build();
 
-        assertThatThrownBy(() -> dsnBounce.init(mailetConfig))
-            .isInstanceOf(MessagingException.class);
-    }
+            assertThatThrownBy(() -> dsnBounce.init(mailetConfig))
+                .isInstanceOf(MessagingException.class);
+        }
 
-    @Test
-    void getRecipientsShouldReturnReversePathOnly() {
-        assertThat(dsnBounce.getRecipients()).containsOnly(SpecialAddress.REVERSE_PATH);
-    }
+        @Test
+        void getRecipientsShouldReturnReversePathOnly() {
+            assertThat(dsnBounce.getRecipients()).containsOnly(SpecialAddress.REVERSE_PATH);
+        }
 
-    @Test
-    void getToShouldReturnReversePathOnly() {
-        assertThat(dsnBounce.getTo()).containsOnly(SpecialAddress.REVERSE_PATH.toInternetAddress());
-    }
+        @Test
+        void getToShouldReturnReversePathOnly() {
+            assertThat(dsnBounce.getTo()).containsOnly(SpecialAddress.REVERSE_PATH.toInternetAddress());
+        }
 
-    @Test
-    void getReversePathShouldReturnNullSpecialAddress() {
-        Mail mail = null;
-        assertThat(dsnBounce.getReversePath(mail)).contains(SpecialAddress.NULL);
+        @Test
+        void getReversePathShouldReturnNullSpecialAddress() {
+            Mail mail = null;
+            assertThat(dsnBounce.getReversePath(mail)).contains(SpecialAddress.NULL);
+        }
     }
 
-    @Test
-    void serviceShouldSendMultipartMailToTheSender() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+    @Nested
+    class GenericTests {
+        @Test
+        void serviceShouldUpdateTheMailStateWhenNoSenderAndPassThroughIsFalse() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
+                .setProperty("passThrough", "false")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        FakeMail mail = FakeMail.builder()
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(senderMailAddress)
+                .attribute(DELIVERY_ERROR_ATTRIBUTE)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
                     .setText("My content"))
                 .recipient("recipient@domain.com")
                 .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+                .remoteAddr("remoteHost")
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        assertThat(sentMail.getSender()).isNull();
-        assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
-        MimeMessage sentMessage = sentMail.getMsg();
-        assertThat(sentMessage.getContentType()).contains("multipart/report;");
-        assertThat(sentMessage.getContentType()).contains("report-type=delivery-status");
-    }
+            assertThat(mail.getState()).isEqualTo(Mail.GHOST);
+        }
 
-    @Test
-    void serviceShouldSendMultipartMailContainingTextPart() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void serviceShouldNotUpdateTheMailStateWhenNoSenderPassThroughHasDefaultValue() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        FakeMail mail = FakeMail.builder()
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(senderMailAddress)
                 .attribute(DELIVERY_ERROR_ATTRIBUTE)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
                     .setText("My content"))
                 .recipient("recipient@domain.com")
                 .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+                .remoteAddr("remoteHost")
                 .build();
 
-        dsnBounce.service(mail);
-
-        String hostname = InetAddress.getLocalHost().getHostName();
-        String expectedContent = "Hi. This is the James mail server at " + hostname + ".\nI'm afraid I wasn't able to deliver your message to the following addresses.\nThis is a permanent error; I've given up. Sorry it didn't work out.  Below\nI include the list of recipients and the reason why I was unable to deliver\nyour message.\n\n" +
-                "Failed recipient(s):\n" + 
-                "recipient@domain.com\n" +
-                "\n" +
-                "Error message:\n" +
-                "Delivery error\n" + 
-                "\n";
+            dsnBounce.service(mail);
 
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        MimeMessage sentMessage = sentMail.getMsg();
-        MimeMultipart content = (MimeMultipart) sentMessage.getContent();
-        BodyPart bodyPart = content.getBodyPart(0);
-        assertThat(bodyPart.getContentType()).isEqualTo("text/plain; charset=us-ascii");
-        assertThat(bodyPart.getContent()).isEqualTo(expectedContent);
-    }
+            assertThat(mail.getState()).isNull();
+        }
 
-    @Test
-    void serviceShouldSendMultipartMailContainingTextPartWhenCustomMessageIsConfigured() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void serviceShouldNotUpdateTheMailStateWhenNoSenderPassThroughIsTrue() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("messageString", "My custom message\n")
+                .setProperty("passThrough", "true")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        FakeMail mail = FakeMail.builder()
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(senderMailAddress)
                 .attribute(DELIVERY_ERROR_ATTRIBUTE)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
                     .setText("My content"))
                 .recipient("recipient@domain.com")
                 .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+                .remoteAddr("remoteHost")
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        String expectedContent = "My custom message\n\n" +
-                "Failed recipient(s):\n" + 
-                "recipient@domain.com\n" +
-                "\n" +
-                "Error message:\n" +
-                "Delivery error\n" + 
-                "\n";
-
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        MimeMessage sentMessage = sentMail.getMsg();
-        MimeMultipart content = (MimeMultipart) sentMessage.getContent();
-        BodyPart bodyPart = content.getBodyPart(0);
-        assertThat(bodyPart.getContentType()).isEqualTo("text/plain; charset=us-ascii");
-        assertThat(bodyPart.getContent()).isEqualTo(expectedContent);
-    }
+            assertThat(mail.getState()).isNull();
+        }
 
-    @Test
-    void serviceShouldSendMultipartMailContainingDSNPart() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void serviceShouldSetTheDateHeaderWhenNone() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
                 .sender(senderMailAddress)
-                .attribute(DELIVERY_ERROR_ATTRIBUTE)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
                     .setText("My content"))
                 .recipient("recipient@domain.com")
                 .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
-                .remoteAddr("remoteHost")
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        String expectedContent = "Reporting-MTA: dns; myhost\n" +
-                "Received-From-MTA: dns; 111.222.333.444\n" +
-                "\n" +
-                "Final-Recipient: rfc822; recipient@domain.com\n" +
-                "Action: failed\n" +
-                "Status: Delivery error\n" +
-                "Diagnostic-Code: X-James; Delivery error\n" +
-                "Last-Attempt-Date: Thu, 8 Sep 2016 14:25:52 XXXXX (UTC)\n";
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            assertThat(sentMail.getSender()).isNull();
+            assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
+            MimeMessage sentMessage = sentMail.getMsg();
+            assertThat(sentMessage.getHeader(RFC2822Headers.DATE)).isNotNull();
+        }
 
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        MimeMessage sentMessage = sentMail.getMsg();
-        MimeMultipart content = (MimeMultipart) sentMessage.getContent();
-        SharedByteArrayInputStream actualContent = (SharedByteArrayInputStream) content.getBodyPart(1).getContent();
-        assertThat(IOUtils.toString(actualContent, StandardCharsets.UTF_8)).isEqualTo(expectedContent);
-    }
-
-    @Test
-    void serviceShouldUpdateTheMailStateWhenNoSenderAndPassThroughIsFalse() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void serviceShouldNotModifyTheDateHeaderWhenAlreadyPresent() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("passThrough", "false")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            String expectedDate = "Wed, 28 Sep 2016 14:25:52 +0000 (UTC)";
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .attribute(DELIVERY_ERROR_ATTRIBUTE)
+                .sender(senderMailAddress)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setText("My content"))
+                    .setText("My content")
+                    .addHeader(RFC2822Headers.DATE, expectedDate))
                 .recipient("recipient@domain.com")
                 .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
-                .remoteAddr("remoteHost")
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        assertThat(mail.getState()).isEqualTo(Mail.GHOST);
-    }
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            assertThat(sentMail.getSender()).isNull();
+            assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
+            MimeMessage sentMessage = sentMail.getMsg();
+            assertThat(sentMessage.getHeader(RFC2822Headers.DATE)[0]).isEqualTo(expectedDate);
+        }
 
-    @Test
-    void serviceShouldNotUpdateTheMailStateWhenNoSenderPassThroughHasDefaultValue() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void dsnBounceShouldAddPrefixToSubjectWhenPrefixIsConfigured() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
+                .setProperty("prefix", "pre")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .attribute(DELIVERY_ERROR_ATTRIBUTE)
+                .sender(MailAddressFixture.ANY_AT_JAMES)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setText("My content"))
-                .recipient("recipient@domain.com")
-                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
-                .remoteAddr("remoteHost")
+                    .setSubject("My subject"))
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        assertThat(mail.getState()).isNull();
-    }
+            assertThat(fakeMailContext.getSentMails()).hasSize(1).allSatisfy(
+                sentMail -> assertThat(sentMail.getSubject()).contains("pre My subject"));
+        }
 
-    @Test
-    void serviceShouldNotUpdateTheMailStateWhenNoSenderPassThroughIsTrue() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void dsnBounceShouldAllowSenderSpecialPostmaster() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("passThrough", "true")
+                .setProperty("sender", "postmaster")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .attribute(DELIVERY_ERROR_ATTRIBUTE)
+                .sender(MailAddressFixture.ANY_AT_JAMES)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setText("My content"))
-                .recipient("recipient@domain.com")
-                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
-                .remoteAddr("remoteHost")
+                    .setSubject("My subject"))
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        assertThat(mail.getState()).isNull();
-    }
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+
+            assertThat(sentMail.getMsg().getFrom())
+                .containsOnly(fakeMailContext.getPostmaster().toInternetAddress());
+            assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
+        }
 
-    @Test
-    void serviceShouldNotAttachTheOriginalMailWhenAttachmentIsEqualToNone() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void dsnBounceShouldAllowSenderSpecialSender() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("attachment", "none")
+                .setProperty("sender", "sender")
+                .setProperty("prefix", "pre")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        FakeMail mail = FakeMail.builder()
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(senderMailAddress)
+                .sender(MailAddressFixture.ANY_AT_JAMES)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setText("My content"))
-                .recipient("recipient@domain.com")
-                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+                    .setSubject("My subject"))
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        assertThat(sentMail.getSender()).isNull();
-        assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
-        MimeMessage sentMessage = sentMail.getMsg();
-        MimeMultipart content = (MimeMultipart) sentMessage.getContent();
-        assertThat(content.getCount()).isEqualTo(2);
-    }
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+
+            assertThat(sentMail.getMsg().getFrom()).containsOnly(mail.getSender().toInternetAddress());
+            assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
+        }
 
-    @Test
-    void serviceShouldAttachTheOriginalMailWhenAttachmentIsEqualToAll() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void dsnBounceShouldAllowSenderSpecialUnaltered() throws Exception {
+
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("attachment", "all")
+                .setProperty("sender", "unaltered")
                 .build();
-        dsnBounce.init(mailetConfig);
-
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        MimeMessage mimeMessage = MimeMessageBuilder.mimeMessageBuilder()
-            .setText("My content")
-            .build();
-        FakeMail mail = FakeMail.builder()
-            .name(MAILET_NAME)
-            .sender(senderMailAddress)
-            .recipient("recipient@domain.com")
-            .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
-            .mimeMessage(mimeMessage)
-            .build();
-        MimeMessage mimeMessageCopy = new MimeMessage(mimeMessage);
-
-        dsnBounce.service(mail);
-
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        assertThat(sentMail.getSender()).isNull();
-        assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
-        MimeMessage sentMessage = sentMail.getMsg();
-        MimeMultipart content = (MimeMultipart) sentMessage.getContent();
-
-        assertThat(sentMail.getMsg().getContentType()).startsWith("multipart/report;");
-        assertThat(MimeMessageUtil.asString((MimeMessage) content.getBodyPart(2).getContent()))
-            .isEqualTo(MimeMessageUtil.asString(mimeMessageCopy));
-    }
+            dsnBounce.init(mailetConfig);
+
+            FakeMail mail = FakeMail.builder()
+                .name(MAILET_NAME)
+                .sender(MailAddressFixture.ANY_AT_JAMES)
+                .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+                    .setSubject("My subject"))
+                .build();
+
+            dsnBounce.service(mail);
 
-    @Test
-    void serviceShouldAttachTheOriginalMailHeadersOnlyWhenAttachmentIsEqualToHeads() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+
+            assertThat(sentMail.getMsg().getFrom()).containsOnly(mail.getSender().toInternetAddress());
+            assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
+        }
+
+        @Test
+        void dsnBounceShouldAllowSenderSpecialAddress() throws Exception {
+
+            MailAddress bounceSender = new MailAddress("bounces@domain.com");
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("attachment", "heads")
+                .setProperty("sender", bounceSender.asPrettyString())
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        FakeMail mail = FakeMail.builder()
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(senderMailAddress)
+                .sender(MailAddressFixture.ANY_AT_JAMES)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setText("My content")
-                    .addHeader("myHeader", "myValue")
-                    .setSubject("mySubject"))
-                .recipient("recipient@domain.com")
-                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+                    .setSubject("My subject"))
                 .build();
 
-        dsnBounce.service(mail);
-
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        assertThat(sentMail.getSender()).isNull();
-        assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
-        MimeMessage sentMessage = sentMail.getMsg();
-        MimeMultipart content = (MimeMultipart) sentMessage.getContent();
-        BodyPart bodyPart = content.getBodyPart(2);
-        SharedByteArrayInputStream actualContent = (SharedByteArrayInputStream) bodyPart.getContent();
-        assertThat(IOUtils.toString(actualContent, StandardCharsets.UTF_8))
-            .contains("Subject: mySubject")
-            .contains("myHeader: myValue");
-        assertThat(bodyPart.getContentType()).isEqualTo("text/rfc822-headers; name=mySubject");
+            dsnBounce.service(mail);
+
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+
+            assertThat(sentMail.getMsg().getFrom()).containsOnly(bounceSender.toInternetAddress());
+            assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
+        }
     }
 
-    @Test
-    void serviceShouldSetTheDateHeaderWhenNone() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+    @Nested
+    class FailedAction {
+        @Test
+        void serviceShouldSendMultipartMailToTheSender() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
                 .sender(senderMailAddress)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
@@ -463,178 +407,242 @@ public class DSNBounceTest {
                 .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        assertThat(sentMail.getSender()).isNull();
-        assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
-        MimeMessage sentMessage = sentMail.getMsg();
-        assertThat(sentMessage.getHeader(RFC2822Headers.DATE)).isNotNull();
-    }
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            assertThat(sentMail.getSender()).isNull();
+            assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
+            MimeMessage sentMessage = sentMail.getMsg();
+            assertThat(sentMessage.getContentType()).contains("multipart/report;");
+            assertThat(sentMessage.getContentType()).contains("report-type=delivery-status");
+        }
 
-    @Test
-    void serviceShouldNotModifyTheDateHeaderWhenAlreadyPresent() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void serviceShouldSendMultipartMailContainingTextPart() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        MailAddress senderMailAddress = new MailAddress("sender@domain.com");
-        String expectedDate = "Wed, 28 Sep 2016 14:25:52 +0000 (UTC)";
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
                 .sender(senderMailAddress)
+                .attribute(DELIVERY_ERROR_ATTRIBUTE)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setText("My content")
-                    .addHeader(RFC2822Headers.DATE, expectedDate))
+                    .setText("My content"))
                 .recipient("recipient@domain.com")
                 .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-        assertThat(sentMail.getSender()).isNull();
-        assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
-        MimeMessage sentMessage = sentMail.getMsg();
-        assertThat(sentMessage.getHeader(RFC2822Headers.DATE)[0]).isEqualTo(expectedDate);
-    }
+            String hostname = InetAddress.getLocalHost().getHostName();
+            String expectedContent = "Hi. This is the James mail server at " + hostname + ".\nI'm afraid I wasn't able to deliver your message to the following addresses.\nThis is a permanent error; I've given up. Sorry it didn't work out.  Below\nI include the list of recipients and the reason why I was unable to deliver\nyour message.\n\n" +
+                "Failed recipient(s):\n" +
+                "recipient@domain.com\n" +
+                "\n" +
+                "Error message:\n" +
+                "Delivery error\n" +
+                "\n";
 
-    @Test
-    void dsnBounceShouldAddPrefixToSubjectWhenPrefixIsConfigured() throws Exception {
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            MimeMessage sentMessage = sentMail.getMsg();
+            MimeMultipart content = (MimeMultipart) sentMessage.getContent();
+            BodyPart bodyPart = content.getBodyPart(0);
+            assertThat(bodyPart.getContentType()).isEqualTo("text/plain; charset=us-ascii");
+            assertThat(bodyPart.getContent()).isEqualTo(expectedContent);
+        }
+
+        @Test
+        void serviceShouldSendMultipartMailContainingTextPartWhenCustomMessageIsConfigured() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("prefix", "pre")
+                .setProperty("messageString", "My custom message\n")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(MailAddressFixture.ANY_AT_JAMES)
+                .sender(senderMailAddress)
+                .attribute(DELIVERY_ERROR_ATTRIBUTE)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setSubject("My subject"))
+                    .setText("My content"))
+                .recipient("recipient@domain.com")
+                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
                 .build();
 
-        dsnBounce.service(mail);
+            dsnBounce.service(mail);
 
-        assertThat(fakeMailContext.getSentMails()).hasSize(1).allSatisfy(
-                sentMail -> assertThat(sentMail.getSubject()).contains("pre My subject"));
-    }
+            String expectedContent = "My custom message\n\n" +
+                "Failed recipient(s):\n" +
+                "recipient@domain.com\n" +
+                "\n" +
+                "Error message:\n" +
+                "Delivery error\n" +
+                "\n";
 
-    @Test
-    void dsnBounceShouldAllowSenderSpecialPostmaster() throws Exception {
-        
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            MimeMessage sentMessage = sentMail.getMsg();
+            MimeMultipart content = (MimeMultipart) sentMessage.getContent();
+            BodyPart bodyPart = content.getBodyPart(0);
+            assertThat(bodyPart.getContentType()).isEqualTo("text/plain; charset=us-ascii");
+            assertThat(bodyPart.getContent()).isEqualTo(expectedContent);
+        }
+
+        @Test
+        void serviceShouldSendMultipartMailContainingDSNPart() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("sender", "postmaster")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(MailAddressFixture.ANY_AT_JAMES)
+                .sender(senderMailAddress)
+                .attribute(DELIVERY_ERROR_ATTRIBUTE)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                    .setSubject("My subject"))
+                    .setText("My content"))
+                .recipient("recipient@domain.com")
+                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+                .remoteAddr("remoteHost")
                 .build();
 
-        dsnBounce.service(mail);
-
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-
-        assertThat(sentMail.getMsg().getFrom())
-                .containsOnly(fakeMailContext.getPostmaster().toInternetAddress());
-        assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
-    }
+            dsnBounce.service(mail);
 
-    @Test
-    void dsnBounceShouldAllowSenderSpecialSender() throws Exception {
+            String expectedContent = "Reporting-MTA: dns; myhost\n" +
+                "Received-From-MTA: dns; 111.222.333.444\n" +
+                "\n" +
+                "Final-Recipient: rfc822; recipient@domain.com\n" +
+                "Action: failed\n" +
+                "Status: Delivery error\n" +
+                "Diagnostic-Code: X-James; Delivery error\n" +
+                "Last-Attempt-Date: Thu, 8 Sep 2016 14:25:52 XXXXX (UTC)\n";
 
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            MimeMessage sentMessage = sentMail.getMsg();
+            MimeMultipart content = (MimeMultipart) sentMessage.getContent();
+            SharedByteArrayInputStream actualContent = (SharedByteArrayInputStream) content.getBodyPart(1).getContent();
+            assertThat(IOUtils.toString(actualContent, StandardCharsets.UTF_8)).isEqualTo(expectedContent);
+        }
+
+        @Test
+        void serviceShouldNotAttachTheOriginalMailWhenAttachmentIsEqualToNone() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("sender", "sender")
-                .setProperty("prefix", "pre")
+                .setProperty("attachment", "none")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(MailAddressFixture.ANY_AT_JAMES)
+                .sender(senderMailAddress)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                        .setSubject("My subject"))
+                    .setText("My content"))
+                .recipient("recipient@domain.com")
+                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
                 .build();
 
-        dsnBounce.service(mail);
-
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
+            dsnBounce.service(mail);
 
-        assertThat(sentMail.getMsg().getFrom()).containsOnly(mail.getSender().toInternetAddress());
-        assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
-    }
-
-    @Test
-    void dsnBounceShouldAllowSenderSpecialUnaltered() throws Exception {
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            assertThat(sentMail.getSender()).isNull();
+            assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
+            MimeMessage sentMessage = sentMail.getMsg();
+            MimeMultipart content = (MimeMultipart) sentMessage.getContent();
+            assertThat(content.getCount()).isEqualTo(2);
+        }
 
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void serviceShouldAttachTheOriginalMailWhenAttachmentIsEqualToAll() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("sender", "unaltered")
+                .setProperty("attachment", "all")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            MimeMessage mimeMessage = MimeMessageBuilder.mimeMessageBuilder()
+                .setText("My content")
+                .build();
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(MailAddressFixture.ANY_AT_JAMES)
-                .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                        .setSubject("My subject"))
+                .sender(senderMailAddress)
+                .recipient("recipient@domain.com")
+                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
+                .mimeMessage(mimeMessage)
                 .build();
+            MimeMessage mimeMessageCopy = new MimeMessage(mimeMessage);
 
-        dsnBounce.service(mail);
-
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
+            dsnBounce.service(mail);
 
-        assertThat(sentMail.getMsg().getFrom()).containsOnly(mail.getSender().toInternetAddress());
-        assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
-    }
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            assertThat(sentMail.getSender()).isNull();
+            assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
+            MimeMessage sentMessage = sentMail.getMsg();
+            MimeMultipart content = (MimeMultipart) sentMessage.getContent();
 
-    @Test
-    void dsnBounceShouldAllowSenderSpecialAddress() throws Exception {
+            assertThat(sentMail.getMsg().getContentType()).startsWith("multipart/report;");
+            assertThat(MimeMessageUtil.asString((MimeMessage) content.getBodyPart(2).getContent()))
+                .isEqualTo(MimeMessageUtil.asString(mimeMessageCopy));
+        }
 
-        MailAddress bounceSender = new MailAddress("bounces@domain.com");
-        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+        @Test
+        void serviceShouldAttachTheOriginalMailHeadersOnlyWhenAttachmentIsEqualToHeads() throws Exception {
+            FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
                 .mailetName(MAILET_NAME)
                 .mailetContext(fakeMailContext)
-                .setProperty("sender", bounceSender.asPrettyString())
+                .setProperty("attachment", "heads")
                 .build();
-        dsnBounce.init(mailetConfig);
+            dsnBounce.init(mailetConfig);
 
-        FakeMail mail = FakeMail.builder()
+            MailAddress senderMailAddress = new MailAddress("sender@domain.com");
+            FakeMail mail = FakeMail.builder()
                 .name(MAILET_NAME)
-                .sender(MailAddressFixture.ANY_AT_JAMES)
+                .sender(senderMailAddress)
                 .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
-                        .setSubject("My subject"))
+                    .setText("My content")
+                    .addHeader("myHeader", "myValue")
+                    .setSubject("mySubject"))
+                .recipient("recipient@domain.com")
+                .lastUpdated(Date.from(Instant.parse("2016-09-08T14:25:52.000Z")))
                 .build();
 
-        dsnBounce.service(mail);
-
-        List<SentMail> sentMails = fakeMailContext.getSentMails();
-        assertThat(sentMails).hasSize(1);
-        SentMail sentMail = sentMails.get(0);
-
-        assertThat(sentMail.getMsg().getFrom()).containsOnly(bounceSender.toInternetAddress());
-        assertThat(sentMail.getRecipients()).containsOnly(mail.getSender());
+            dsnBounce.service(mail);
+
+            List<SentMail> sentMails = fakeMailContext.getSentMails();
+            assertThat(sentMails).hasSize(1);
+            SentMail sentMail = sentMails.get(0);
+            assertThat(sentMail.getSender()).isNull();
+            assertThat(sentMail.getRecipients()).containsOnly(senderMailAddress);
+            MimeMessage sentMessage = sentMail.getMsg();
+            MimeMultipart content = (MimeMultipart) sentMessage.getContent();
+            BodyPart bodyPart = content.getBodyPart(2);
+            SharedByteArrayInputStream actualContent = (SharedByteArrayInputStream) bodyPart.getContent();
+            assertThat(IOUtils.toString(actualContent, StandardCharsets.UTF_8))
+                .contains("Subject: mySubject")
+                .contains("myHeader: myValue");
+            assertThat(bodyPart.getContentType()).isEqualTo("text/rfc822-headers; name=mySubject");
+        }
     }
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org