JAMES-2529 Integration tests for JMAP filtering on incoming mails

Exercise all fields and a basic subset of comparators.
More fine grained testing is done in unit tests.


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

Branch: refs/heads/master
Commit: b53509c2ced5710305b5302270ced65ad5f5d1ee
Parents: 7527dae
Author: Benoit Tellier <btell...@linagora.com>
Authored: Wed Aug 29 11:52:09 2018 +0700
Committer: Antoine Duprat <adup...@linagora.com>
Committed: Thu Aug 30 15:11:54 2018 +0200

----------------------------------------------------------------------
 .../src/test/resources/mailetcontainer.xml      |    1 +
 .../apache/james/jmap/JmapCommonRequests.java   |   19 +
 .../jmap/methods/integration/FilterTest.java    | 1572 +++++++++++++++++-
 .../src/test/resources/mailetcontainer.xml      |    3 +-
 4 files changed, 1582 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
index 887c947..2ecff3f 100644
--- 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
@@ -72,6 +72,7 @@
             <mailet match="IsMarkedAsSpam" class="WithStorageDirective">
                 <targetFolderName>Spam</targetFolderName>
             </mailet>
+            <mailet match="RecipientIsLocal" 
class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
             <mailet match="RecipientIsLocal" class="LocalDelivery"/>
             <mailet match="HostIsLocal" class="ToProcessor">
                 <processor>local-address-error</processor>

http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
index ef61472..fe3f84d 100644
--- 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapCommonRequests.java
@@ -32,6 +32,7 @@ import java.util.Map;
 
 import org.apache.james.jmap.api.access.AccessToken;
 import org.apache.james.mailbox.Role;
+import org.apache.james.mailbox.model.MailboxId;
 
 import io.restassured.builder.ResponseSpecBuilder;
 import io.restassured.specification.ResponseSpecification;
@@ -85,6 +86,24 @@ public class JmapCommonRequests {
         }
     }
 
+    public static boolean isAnyMessageFoundInRecipientsMailbox(AccessToken 
recipientToken, MailboxId mailboxId) {
+        try {
+            with()
+                .header("Authorization", recipientToken.serialize())
+                .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" 
+ mailboxId.serialize() + "\"]}}, \"#0\"]]")
+            .when()
+                .post("/jmap")
+            .then()
+                .statusCode(200)
+                .body(NAME, equalTo("messageList"))
+                .body(ARGUMENTS + ".messageIds", hasSize(1));
+            return true;
+
+        } catch (AssertionError e) {
+            return false;
+        }
+    }
+
     public static String getInboxId(AccessToken accessToken) {
         return getMailboxId(accessToken, Role.INBOX);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
index 643c844..f56615c 100644
--- 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/FilterTest.java
@@ -22,13 +22,20 @@ package org.apache.james.jmap.methods.integration;
 import static io.restassured.RestAssured.given;
 import static io.restassured.RestAssured.with;
 import static 
org.apache.james.jmap.HttpJmapAuthentication.authenticateJamesUser;
+import static org.apache.james.jmap.JmapCommonRequests.getOutboxId;
 import static org.apache.james.jmap.JmapURIBuilder.baseUri;
 import static org.apache.james.jmap.TestingConstants.ALICE;
 import static org.apache.james.jmap.TestingConstants.ALICE_PASSWORD;
 import static org.apache.james.jmap.TestingConstants.ARGUMENTS;
+import static org.apache.james.jmap.TestingConstants.BOB;
+import static org.apache.james.jmap.TestingConstants.BOB_PASSWORD;
+import static org.apache.james.jmap.TestingConstants.CEDRIC;
 import static org.apache.james.jmap.TestingConstants.DOMAIN;
 import static org.apache.james.jmap.TestingConstants.NAME;
+import static org.apache.james.jmap.TestingConstants.calmlyAwait;
 import static org.apache.james.jmap.TestingConstants.jmapRequestSpecBuilder;
+import static org.apache.james.mailbox.model.MailboxConstants.INBOX;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.hasSize;
@@ -36,8 +43,11 @@ import static org.hamcrest.Matchers.hasSize;
 import java.io.IOException;
 
 import org.apache.james.GuiceJamesServer;
+import org.apache.james.jmap.JmapCommonRequests;
 import org.apache.james.jmap.api.access.AccessToken;
 import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.modules.MailboxProbeImpl;
 import org.apache.james.probe.DataProbe;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.JmapGuiceProbe;
@@ -54,21 +64,31 @@ public abstract class FilterTest {
     protected abstract MailboxId randomMailboxId();
 
     private AccessToken accessToken;
+    private AccessToken bobAccessToken;
     private GuiceJamesServer jmapServer;
 
+    private MailboxId matchedMailbox;
+    private MailboxId inbox;
+
     @Before
     public void setup() throws Throwable {
         jmapServer = createJmapServer();
         jmapServer.start();
 
         RestAssured.requestSpecification = jmapRequestSpecBuilder
-                
.setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort())
-                .build();
+            .setPort(jmapServer.getProbe(JmapGuiceProbe.class).getJmapPort())
+            .build();
 
         DataProbe dataProbe = jmapServer.getProbe(DataProbeImpl.class);
         dataProbe.addDomain(DOMAIN);
         dataProbe.addUser(ALICE, ALICE_PASSWORD);
+        dataProbe.addUser(BOB, BOB_PASSWORD);
         accessToken = authenticateJamesUser(baseUri(jmapServer), ALICE, 
ALICE_PASSWORD);
+        bobAccessToken = authenticateJamesUser(baseUri(jmapServer), BOB, 
BOB_PASSWORD);
+
+        MailboxProbeImpl mailboxProbe = 
jmapServer.getProbe(MailboxProbeImpl.class);
+        matchedMailbox = mailboxProbe.createMailbox(MailboxPath.forUser(ALICE, 
"matched"));
+        inbox = mailboxProbe.createMailbox(MailboxPath.forUser(ALICE, INBOX));
     }
 
     @After
@@ -100,7 +120,7 @@ public abstract class FilterTest {
         MailboxId mailbox1 = randomMailboxId();
         MailboxId mailbox2 = randomMailboxId();
 
-        with()
+        given()
             .header("Authorization", accessToken.serialize())
             .body("[[" +
                   "  \"setFilter\", " +
@@ -123,7 +143,11 @@ public abstract class FilterTest {
                   "  ]}, " +
                   "\"#0\"" +
                   "]]")
-            .post("/jmap");
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
         with()
             .header("Authorization", accessToken.serialize())
             .body("[[" +
@@ -147,7 +171,10 @@ public abstract class FilterTest {
                   "  ]}, " +
                   "\"#0\"" +
                   "]]")
-            .post("/jmap");
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
 
         given()
             .header("Authorization", accessToken.serialize())
@@ -336,7 +363,7 @@ public abstract class FilterTest {
         MailboxId mailbox1 = randomMailboxId();
         MailboxId mailbox2 = randomMailboxId();
 
-        with()
+        given()
             .header("Authorization", accessToken.serialize())
             .body("[[" +
                   "  \"setFilter\", " +
@@ -373,7 +400,10 @@ public abstract class FilterTest {
                   "  ]}, " +
                   "\"#0\"" +
                   "]]")
-            .post("/jmap");
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
 
         given()
             .header("Authorization", accessToken.serialize())
@@ -406,7 +436,7 @@ public abstract class FilterTest {
     public void setFilterShouldClearPreviouslyStoredRulesWhenEmptyBody() {
         MailboxId mailbox = randomMailboxId();
 
-        with()
+        given()
             .header("Authorization", accessToken.serialize())
             .body("[[" +
                   "  \"setFilter\", " +
@@ -429,7 +459,10 @@ public abstract class FilterTest {
                   "  ]}, " +
                   "\"#0\"" +
                   "]]")
-            .post("/jmap");
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
 
         with()
             .header("Authorization", accessToken.serialize())
@@ -440,7 +473,10 @@ public abstract class FilterTest {
                   "  }, " +
                   "\"#0\"" +
                   "]]")
-            .post("/jmap");
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
 
         given()
             .header("Authorization", accessToken.serialize())
@@ -461,7 +497,7 @@ public abstract class FilterTest {
     public void allFieldsAndComparatorsShouldBeSupported() {
         MailboxId mailbox = randomMailboxId();
 
-        with()
+        given()
             .header("Authorization", accessToken.serialize())
             .body("[[" +
                   "  \"setFilter\", " +
@@ -540,7 +576,10 @@ public abstract class FilterTest {
                   "  ]}, " +
                   "\"#0\"" +
                   "]]")
-            .post("/jmap");
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
 
         given()
             .header("Authorization", accessToken.serialize())
@@ -572,4 +611,1513 @@ public abstract class FilterTest {
             .body(ARGUMENTS + ".singleton[4].condition.comparator", 
equalTo("contains"));
     }
 
+    @Test
+    public void messageShouldBeAppendedInSpecificMailboxWhenFromRuleMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + BOB + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap");
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void messageShouldBeAppendedInSpecificMailboxWhenToRuleMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails to cedric\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"to\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"},{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void messageShouldBeAppendedInSpecificMailboxWhenCcRuleMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails cc-ed to cedric\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"cc\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenRecipientRuleMatchesCc() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails cc-ed to cedric\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"recipient\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenRecipientRuleMatchesTo() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails cc-ed to cedric\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"recipient\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + CEDRIC + 
"\"}]," +
+            "      \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenSubjectRuleMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"subject\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"matchme\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"},{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+            "      \"subject\": \"matchme\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void messageShouldBeAppendedInInboxWhenFromDoesNotMatchRule() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void messageShouldBeAppendedInInboxWhenToDoesNotMatchRule() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails to cedric\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"to\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void messageShouldBeAppendedInInboxWhenCcDoesNotMatchRule() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails cc-ed to cedric\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"cc\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + BOB + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void messageShouldBeAppendedInInboxWhenRecipientDoesNotMatchRule() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails cc-ed to cedric\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"recipient\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + CEDRIC + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"cc\": [{ \"name\": \"Cedric\", \"email\": \"" + BOB + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInInboxWhenSubjectRuleDoesNotMatchRule() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"subject\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"matchme\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"},{ \"name\": \"Cedric\", \"email\": \"" + CEDRIC + "\"}]," +
+            "      \"subject\": \"nomatch\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenContainsComparatorMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"bo\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInInboxWhenContainsComparatorDoesNotMatch() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"ced\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenExactlyEqualsMatchesName() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"exactly-equals\"," +
+                "        \"value\": \"Bob\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + 
"\"}," +
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenExactlyEqualsMatchesAddress() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"exactly-equals\"," +
+                "        \"value\": \"" + BOB + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + 
"\"}," +
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenExactlyEqualsMatchesFullHeader() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"exactly-equals\"," +
+                "        \"value\": \"Bob <" + BOB + ">\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + 
"\"}," +
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInInboxWhenExactlyEqualsComparatorDoesNotMatch() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"exactly-equals\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"nomatch\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenNotContainsComparatorMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"not-contains\"," +
+                "        \"value\": \"other\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInInboxWhenNotContainsComparatorDoesNotMatch() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"not-contains\"," +
+                "        \"value\": \"bob\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenContainsNotExactlyEqualsMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"not-exactly-equals\"," +
+                "        \"value\": \"nomatch\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + 
"\"}," +
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInInboxWhenNotExactlyEqualsMatchesAddress() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"not-exactly-equals\"," +
+                "        \"value\": \"" + BOB + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + 
"\"}," +
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInInboxWhenNotExactlyEqualsMatchesFullHeader() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"not-exactly-equals\"," +
+                "        \"value\": \"Bob <" + BOB + ">\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Bob\", \"email\": \"" + BOB + 
"\"}," +
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInInboxWhenNotExactlyEqualsComparatorMatchesName() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"not-exactly-equals\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"Bob\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+    }
+
+    @Test
+    public void messageShouldBeAppendedInSpecificMailboxWhenFirstRuleMatches() 
{
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + BOB + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }," +
+                "    {" +
+                "      \"id\": \"3000-346\"," +
+                "      \"name\": \"Emails to alice\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"to\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + ALICE + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap");
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void 
messageShouldBeAppendedInSpecificMailboxWhenSecondRuleMatches() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"unkn...@james.org\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }," +
+                "    {" +
+                "      \"id\": \"3000-346\"," +
+                "      \"name\": \"Emails to alice\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"to\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + ALICE + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap");
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+    }
+
+    @Test
+    public void inboxShouldBeEmptyWhenFromRuleMatchesInSpecificMailbox() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"" + BOB + "\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap");
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox));
+        
assertThat(JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
inbox)).isFalse();
+    }
+
+    @Test
+    public void matchedMailboxShouldBeEmptyWhenFromRuleDoesntMatch() {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[" +
+                "  \"setFilter\", " +
+                "  {" +
+                "    \"singleton\": [" +
+                "    {" +
+                "      \"id\": \"3000-345\"," +
+                "      \"name\": \"Emails from bob\"," +
+                "      \"condition\": {" +
+                "        \"field\": \"from\"," +
+                "        \"comparator\": \"contains\"," +
+                "        \"value\": \"unkn...@james.org\"" +
+                "      }," +
+                "      \"action\": {" +
+                "        \"appendIn\": {" +
+                "          \"mailboxIds\": [\"" + matchedMailbox.serialize() + 
"\"]" +
+                "        }" +
+                "      }" +
+                "    }" +
+                "  ]}, " +
+                "\"#0\"" +
+                "]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        String messageCreationId = "creationId1337";
+        String requestBody = "[[" +
+            "  \"setMessages\"," +
+            "  {" +
+            "    \"create\": { \"" + messageCreationId  + "\" : {" +
+            "      \"from\": { \"name\": \"Me\", \"email\": \"" + BOB + "\"}," 
+
+            "      \"to\": [{ \"name\": \"Alice\", \"email\": \"" + ALICE + 
"\"}]," +
+            "      \"subject\": \"subject\"," +
+            "      \"mailboxIds\": [\"" + getOutboxId(bobAccessToken) + "\"]" +
+            "    }}" +
+            "  }," +
+            "  \"#0\"" +
+            "]]";
+
+        with()
+            .header("Authorization", bobAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap");
+
+        calmlyAwait.until(
+            () -> 
JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, inbox));
+        
assertThat(JmapCommonRequests.isAnyMessageFoundInRecipientsMailbox(accessToken, 
matchedMailbox)).isFalse();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/b53509c2/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
index c783fd3..c890709 100644
--- 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/resources/mailetcontainer.xml
@@ -73,7 +73,8 @@
             <mailet match="IsMarkedAsSpam" class="WithStorageDirective">
                 <targetFolderName>Spam</targetFolderName>
             </mailet>
-             <mailet match="RecipientIsLocal" class="LocalDelivery"/>
+            <mailet match="RecipientIsLocal" 
class="org.apache.james.jmap.mailet.filter.JMAPFiltering"/>
+            <mailet match="RecipientIsLocal" class="LocalDelivery"/>
             <mailet match="HostIsLocal" class="ToProcessor">
                 <processor>local-address-error</processor>
                 <notice>550 - Requested action not taken: no such user 
here</notice>


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

Reply via email to