You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ad...@apache.org on 2017/09/13 10:57:47 UTC

[21/24] james-project git commit: JAMES-2139 IT test from mailet

JAMES-2139 IT test from mailet


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/895a0042
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/895a0042
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/895a0042

Branch: refs/heads/master
Commit: 895a00425f3dc2da42d4ca3def1caa7db8782384
Parents: bdedd0b
Author: quynhn <qn...@linagora.com>
Authored: Wed Sep 6 18:00:36 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Sep 13 10:23:33 2017 +0200

----------------------------------------------------------------------
 server/mailet/integration-testing/pom.xml       |  10 +
 .../james/mailets/TemporaryJamesServer.java     |  11 +-
 .../configuration/ProcessorConfiguration.java   |   4 +
 .../transport/mailets/GroupMappingTest.java     | 377 +++++++++++++++++++
 .../apache/james/utils/IMAPMessageReader.java   |  11 +
 .../apache/james/utils/SMTPMessageSender.java   |  10 +-
 6 files changed, 416 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/pom.xml b/server/mailet/integration-testing/pom.xml
index 82b5000..a148d31 100644
--- a/server/mailet/integration-testing/pom.xml
+++ b/server/mailet/integration-testing/pom.xml
@@ -89,6 +89,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-webadmin-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
             <scope>test</scope>
@@ -103,6 +108,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>com.jayway.restassured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>com.rabbitmq</groupId>
             <artifactId>amqp-client</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
index 387e419..55f3f05 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/TemporaryJamesServer.java
@@ -36,9 +36,11 @@ import org.apache.james.MemoryJamesServerMain;
 import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.modules.TestJMAPServerModule;
 import org.apache.james.utils.GuiceProbe;
+import org.apache.james.webadmin.WebAdminConfiguration;
 import org.junit.rules.TemporaryFolder;
 
 import com.google.common.collect.ImmutableList;
+import com.google.inject.AbstractModule;
 import com.google.inject.Module;
 
 public class TemporaryJamesServer {
@@ -56,11 +58,10 @@ public class TemporaryJamesServer {
         jamesServer = new GuiceJamesServer()
             .combineWith(MemoryJamesServerMain.inMemoryServerModule)
             .overrideWith((binder) -> binder.bind(PersistenceAdapter.class).to(MemoryPersistenceAdapter.class))
-            .overrideWith(ImmutableList.<Module>builder().addAll(Arrays.asList(additionalModules))
-                .add(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
-                .add(new TemporaryFilesystemModule(temporaryFolder))
-                .build()
-                .toArray(new Module[additionalModules.length + 2]));
+            .overrideWith(additionalModules)
+            .overrideWith(new TestJMAPServerModule(LIMIT_TO_3_MESSAGES))
+            .overrideWith(new TemporaryFilesystemModule(temporaryFolder))
+            .overrideWith((binder) -> binder.bind(WebAdminConfiguration.class).toProvider(WebAdminConfiguration::testingConfiguration));
 
         jamesServer.start();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
index 00128f1..cf95d69 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/ProcessorConfiguration.java
@@ -30,6 +30,10 @@ public class ProcessorConfiguration implements SerializableAsXml {
         return new Builder();
     }
 
+    public static Builder transport() {
+        return builder().state("transport");
+    }
+
     public static class Builder {
 
         private String state;

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
new file mode 100644
index 0000000..37b16bd
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/GroupMappingTest.java
@@ -0,0 +1,377 @@
+/****************************************************************
+ * 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.james.transport.mailets;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import javax.mail.internet.MimeMessage;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailets.TemporaryJamesServer;
+import org.apache.james.mailets.configuration.CommonProcessors;
+import org.apache.james.mailets.configuration.MailetConfiguration;
+import org.apache.james.mailets.configuration.MailetContainer;
+import org.apache.james.mailets.configuration.ProcessorConfiguration;
+import org.apache.james.modules.MailboxProbeImpl;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.WebAdminGuiceProbe;
+import org.apache.james.webadmin.routes.GroupsRoutes;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.MimeMessageBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.jayway.awaitility.Awaitility;
+import com.jayway.awaitility.Duration;
+import com.jayway.awaitility.core.ConditionFactory;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.specification.RequestSpecification;
+
+public class GroupMappingTest {
+    private static final String LOCALHOST_IP = "127.0.0.1";
+    private static final int IMAP_PORT = 1143;
+    private static final int SMTP_PORT = 1025;
+    private static final String PASSWORD = "secret";
+
+    private static final String DOMAIN1 = "domain1.com";
+    private static final String DOMAIN2 = "domain2.com";
+
+    private static final String SENDER = "fromUser@" + DOMAIN1;
+    private static final String GROUP_ON_DOMAIN1 = "group@" + DOMAIN1;
+    private static final String GROUP_ON_DOMAIN2 = "group@" + DOMAIN2;
+
+    private static final String USER_DOMAIN1 = "user@" + DOMAIN1;
+    private static final String USER_DOMAIN2 = "user@" + DOMAIN2;
+    private static final String MESSAGE_CONTENT = "any text";
+
+    private TemporaryJamesServer jamesServer;
+    private ConditionFactory calmlyAwait;
+    private MimeMessage message;
+    private DataProbe dataProbe;
+    private RequestSpecification restApiRequest;
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+    @Before
+    public void setup() throws Exception {
+        MailetContainer mailetContainer = MailetContainer.builder()
+            .postmaster("postmaster@" + DOMAIN1)
+            .threads(5)
+            .addProcessor(CommonProcessors.root())
+            .addProcessor(CommonProcessors.error())
+            .addProcessor(ProcessorConfiguration.transport()
+                .enableJmx(true)
+                .addMailet(MailetConfiguration.builder()
+                    .match("All")
+                    .clazz("RemoveMimeHeader")
+                    .addProperty("name", "bcc")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("All")
+                    .clazz("RecipientRewriteTable")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("RecipientIsLocal")
+                    .clazz("org.apache.james.jmap.mailet.VacationMailet")
+                    .build())
+                .addMailet(MailetConfiguration.builder()
+                    .match("RecipientIsLocal")
+                    .clazz("LocalDelivery")
+                    .build())
+                .build())
+            .build();
+
+        jamesServer = new TemporaryJamesServer(temporaryFolder, mailetContainer);
+        Duration slowPacedPollInterval = Duration.FIVE_HUNDRED_MILLISECONDS;
+        calmlyAwait = Awaitility.with().pollInterval(slowPacedPollInterval).and().with().pollDelay(slowPacedPollInterval).await();
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DOMAIN1);
+        dataProbe.addDomain(DOMAIN2);
+
+        dataProbe.addUser(SENDER, PASSWORD);
+
+        dataProbe.addUser(USER_DOMAIN1, PASSWORD);
+        dataProbe.addUser(USER_DOMAIN2, PASSWORD);
+
+        jamesServer.getProbe(MailboxProbeImpl.class).createMailbox(MailboxConstants.USER_NAMESPACE, USER_DOMAIN1, "INBOX");
+        jamesServer.getProbe(MailboxProbeImpl.class).createMailbox(MailboxConstants.USER_NAMESPACE, USER_DOMAIN2, "INBOX");
+
+        restApiRequest = RestAssured.given()
+            .port(jamesServer.getProbe(WebAdminGuiceProbe.class).getWebAdminPort());
+
+        message = MimeMessageBuilder.mimeMessageBuilder()
+            .setSubject("test")
+            .setText(MESSAGE_CONTENT)
+            .build();
+    }
+
+    @After
+    public void tearDown() {
+        jamesServer.shutdown();
+    }
+
+    @Test
+    public void messageShouldRedirectToUserWhenBelongingToGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN1, PASSWORD));
+
+            String processedMessage = imapMessageReader.readFirstMessageInInbox(USER_DOMAIN1, PASSWORD);
+
+            assertThat(processedMessage).contains(MESSAGE_CONTENT);
+        }
+
+    }
+
+    @Test
+    public void messageShouldRedirectToUserDoesNotHaveSameDomainWhenBelongingToGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+
+            String processedMessage = imapMessageReader.readFirstMessageInInbox(USER_DOMAIN2, PASSWORD);
+
+            assertThat(processedMessage).contains(MESSAGE_CONTENT);
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectToAllUsersBelongingToGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN1, PASSWORD, 1));
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN2, PASSWORD, 1));
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectWhenGroupBelongingToAnotherGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+
+            String processedMessage = imapMessageReader.readFirstMessageInInbox(USER_DOMAIN2, PASSWORD);
+
+            assertThat(processedMessage).contains(MESSAGE_CONTENT);
+        }
+    }
+
+    @Test
+    public void messageShouldNotBeDuplicatedWhenUserBelongingToTwoGroups() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN1, PASSWORD, 1));
+        }
+    }
+
+    @Test
+    public void messageShouldNotBeDuplicatedWhenRecipientIsAlsoPartOfGroup() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipients(new MailAddress(GROUP_ON_DOMAIN1), new MailAddress(USER_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.countReceivedMessage(USER_DOMAIN1, PASSWORD, 1));
+        }
+    }
+
+    @Test
+    public void groupMappingShouldSupportTreeStructure() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN2))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN1, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldNotBeSentWhenGroupLoopMapping() throws Exception {
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + GROUP_ON_DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + GROUP_ON_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+            IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHaveNotBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userDoesNotReceiveMessage(USER_DOMAIN1, PASSWORD));
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userDoesNotReceiveMessage(USER_DOMAIN2, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectToUserWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(DOMAIN1, DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldNotSendToUserBelongingToGroupWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(DOMAIN1, DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN1 + "/" + USER_DOMAIN1);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userDoesNotReceiveMessage(USER_DOMAIN1, PASSWORD));
+        }
+    }
+
+    @Test
+    public void messageShouldRedirectToGroupWhenDomainMapping() throws Exception {
+        dataProbe.addDomainAliasMapping(DOMAIN1, DOMAIN2);
+
+        restApiRequest.put(GroupsRoutes.ROOT_PATH + "/" + GROUP_ON_DOMAIN2 + "/" + USER_DOMAIN2);
+
+        Mail mail = FakeMail.builder()
+            .mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress(GROUP_ON_DOMAIN1))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, DOMAIN1);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(USER_DOMAIN2, PASSWORD));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
----------------------------------------------------------------------
diff --git a/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java b/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
index fc05bde..8fb5d68 100644
--- a/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
+++ b/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
@@ -43,6 +43,17 @@ public class IMAPMessageReader implements Closeable {
         imapClient.select(mailbox);
     }
 
+    public boolean countReceivedMessage(String user, String password, int numberOfMessages) throws IOException {
+        return countReceivedMessageInMailbox(user, password, INBOX, numberOfMessages);
+    }
+
+    public boolean countReceivedMessageInMailbox(String user, String password, String mailbox, int numberOfMessages) throws IOException {
+        connectAndSelect(user, password, mailbox);
+
+        return imapClient.getReplyString()
+            .contains(numberOfMessages + " EXISTS");
+    }
+
     public boolean userReceivedMessage(String user, String password) throws IOException {
         return userReceivedMessageInMailbox(user, password, INBOX);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/895a0042/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
----------------------------------------------------------------------
diff --git a/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
index 2a0e5fc..b08c5d2 100644
--- a/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
+++ b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
@@ -31,10 +31,10 @@ import javax.mail.MessagingException;
 
 import org.apache.commons.net.smtp.AuthenticatingSMTPClient;
 import org.apache.commons.net.smtp.SMTPClient;
+import org.apache.james.core.MailAddress;
 import org.apache.mailet.Mail;
 
 import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
 import com.google.common.base.Throwables;
 
 public class SMTPMessageSender implements Closeable {
@@ -92,7 +92,9 @@ public class SMTPMessageSender implements Closeable {
             String from = mail.getSender().asString();
             smtpClient.helo(senderDomain);
             smtpClient.setSender(from);
-            smtpClient.rcpt("<" + Joiner.on(", ").join(mail.getRecipients()) + ">");
+            for (MailAddress mailAddress : mail.getRecipients()) {
+                smtpClient.addRecipient(mailAddress.asString());
+            }
             smtpClient.sendShortMessageData(asString(mail.getMessage()));
         } catch (IOException e) {
             throw Throwables.propagate(e);
@@ -110,6 +112,10 @@ public class SMTPMessageSender implements Closeable {
             .contains("250 2.6.0 Message received");
     }
 
+    public boolean messageHaveNotBeenSent() throws IOException {
+        return !messageHasBeenSent();
+    }
+
     @Override
     public void close() throws IOException {
         smtpClient.disconnect();


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