james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From adup...@apache.org
Subject [3/3] james-project git commit: JAMES-1675 Implement SetMessages: destroy
Date Mon, 08 Feb 2016 14:01:10 GMT
JAMES-1675 Implement SetMessages: destroy


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

Branch: refs/heads/master
Commit: 6665a49e61bb241839da39738d6b798bdd8a572c
Parents: 7fca1ee
Author: Antoine Duprat <antduprat@gmail.com>
Authored: Wed Jan 20 16:53:16 2016 +0100
Committer: Antoine Duprat <antduprat@gmail.com>
Committed: Mon Feb 8 15:00:00 2016 +0100

----------------------------------------------------------------------
 .../org/apache/james/jmap/MethodsModule.java    |   2 +
 .../protocols/jmap-integration-testing/pom.xml  |   6 +
 .../jmap/methods/SetMessagesMethodTest.java     | 287 +++++++++++++++++++
 .../CassandraSetMessagesMethodTest.java         |  35 +++
 .../exceptions/MessageNotFoundException.java    |  23 ++
 .../james/jmap/methods/SetMessagesMethod.java   | 145 ++++++++++
 .../org/apache/james/jmap/model/MessageId.java  |   3 +-
 .../org/apache/james/jmap/model/SetError.java   |  80 ++++++
 .../james/jmap/model/SetMessagesRequest.java    | 126 ++++++++
 .../james/jmap/model/SetMessagesResponse.java   | 188 ++++++++++++
 .../apache/james/jmap/model/SetErrorTest.java   |  59 ++++
 .../jmap/model/SetMessagesRequestTest.java      |  96 +++++++
 .../jmap/model/SetMessagesResponseTest.java     |  86 ++++++
 13 files changed, 1135 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
----------------------------------------------------------------------
diff --git a/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java b/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
index c36619d..71e2dcd 100644
--- a/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
+++ b/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
@@ -28,6 +28,7 @@ import org.apache.james.jmap.methods.JmapRequestParserImpl;
 import org.apache.james.jmap.methods.JmapResponseWriter;
 import org.apache.james.jmap.methods.JmapResponseWriterImpl;
 import org.apache.james.jmap.methods.Method;
+import org.apache.james.jmap.methods.SetMessagesMethod;
 import org.apache.james.mailbox.cassandra.CassandraId;
 
 import com.google.inject.AbstractModule;
@@ -50,6 +51,7 @@ public class MethodsModule extends AbstractModule {
         methods.addBinding().to(new TypeLiteral<GetMailboxesMethod<CassandraId>>(){});
         methods.addBinding().to(new TypeLiteral<GetMessageListMethod<CassandraId>>(){});
         methods.addBinding().to(new TypeLiteral<GetMessagesMethod<CassandraId>>(){});
+        methods.addBinding().to(new TypeLiteral<SetMessagesMethod<CassandraId>>(){});
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap-integration-testing/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/pom.xml b/server/protocols/jmap-integration-testing/pom.xml
index 655c7e9..b3ada4c 100644
--- a/server/protocols/jmap-integration-testing/pom.xml
+++ b/server/protocols/jmap-integration-testing/pom.xml
@@ -201,6 +201,12 @@
                     <version>${cassandra-unit.version}</version>
                     <scope>test</scope>
                 </dependency>
+                <dependency>
+                    <groupId>org.hamcrest</groupId>
+                    <artifactId>java-hamcrest</artifactId>
+                    <version>2.0.0.0</version>
+                    <scope>test</scope>
+                </dependency>
             </dependencies>
             <build>
                 <plugins>

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/SetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/SetMessagesMethodTest.java b/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/SetMessagesMethodTest.java
new file mode 100644
index 0000000..bbe2e57
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/SetMessagesMethodTest.java
@@ -0,0 +1,287 @@
+/****************************************************************
+ * 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.jmap.methods;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
+import static org.hamcrest.collection.IsMapWithSize.anEmptyMap;
+
+import java.io.ByteArrayInputStream;
+import java.util.Date;
+
+import javax.mail.Flags;
+
+import org.apache.james.backends.cassandra.EmbeddedCassandra;
+import org.apache.james.jmap.JmapAuthentication;
+import org.apache.james.jmap.JmapServer;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class SetMessagesMethodTest {
+
+    private static final String NAME = "[0][0]";
+    private static final String ARGUMENTS = "[0][1]";
+
+    private TemporaryFolder temporaryFolder = new TemporaryFolder();
+    private EmbeddedElasticSearch embeddedElasticSearch = new EmbeddedElasticSearch(temporaryFolder);
+    private EmbeddedCassandra cassandra = EmbeddedCassandra.createStartServer();
+    private JmapServer jmapServer = jmapServer(temporaryFolder, embeddedElasticSearch, cassandra);
+
+    protected abstract JmapServer jmapServer(TemporaryFolder temporaryFolder, EmbeddedElasticSearch embeddedElasticSearch, EmbeddedCassandra cassandra);
+
+    @Rule
+    public RuleChain chain = RuleChain
+        .outerRule(temporaryFolder)
+        .around(embeddedElasticSearch)
+        .around(jmapServer);
+
+    private AccessToken accessToken;
+    private String username;
+
+    @Before
+    public void setup() throws Exception {
+        RestAssured.port = jmapServer.getPort();
+        RestAssured.config = newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
+
+        String domain = "domain.tld";
+        username = "username@" + domain;
+        String password = "password";
+        jmapServer.serverProbe().addDomain(domain);
+        jmapServer.serverProbe().addUser(username, password);
+        jmapServer.serverProbe().createMailbox("#private", "username", "inbox");
+        accessToken = JmapAuthentication.authenticateJamesUser(username, password);
+    }
+
+    @Test
+    public void setMessagesShouldReturnErrorNotSupportedWhenRequestContainsNonNullAccountId() throws Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"accountId\": \"1\"}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("error"))
+            .body(ARGUMENTS + ".type", equalTo("Not yet implemented"));
+    }
+
+    @Test
+    public void setMessagesShouldReturnErrorNotSupportedWhenRequestContainsNonNullIfInState() throws Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"ifInState\": \"1\"}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("error"))
+            .body(ARGUMENTS + ".type", equalTo("Not yet implemented"));
+    }
+
+    @Test
+    public void setMessagesShouldReturnNotDestroyedWhenUnknownMailbox() throws Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + "|unknown|1\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".destroyed", empty())
+            .body(ARGUMENTS + ".notDestroyed", hasEntry(username + "|unknown|1", 
+                    ImmutableMap.of("type", "anErrorOccurred",
+                            "description", "An error occurred while deleting message " + username + "|unknown|1")));
+    }
+
+    @Test
+    public void setMessagesShouldReturnNotDestroyedWhenNoMatchingMessage() throws Exception {
+        jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + "|mailbox|12345\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".destroyed", empty())
+            .body(ARGUMENTS + ".notDestroyed", hasEntry(username + "|mailbox|12345", 
+                    ImmutableMap.of("type", "notFound",
+                            "description", "The message " + username + "|mailbox|12345 can't be found")));
+    }
+
+    @Test
+    public void setMessagesShouldReturnDestroyedWhenMatchingMessage() throws Exception {
+        jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        embeddedElasticSearch.awaitForElasticSearch();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + "|mailbox|1\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".notDestroyed", anEmptyMap())
+            .body(ARGUMENTS + ".destroyed", hasSize(1))
+            .body(ARGUMENTS + ".destroyed", contains(username + "|mailbox|1"));
+    }
+
+    @Test
+    public void setMessagesShouldDeleteMessageWhenMatchingMessage() throws Exception {
+        // Given
+        jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        embeddedElasticSearch.awaitForElasticSearch();
+
+        // When
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + "|mailbox|1\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        // Then
+        given()
+           .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + username + "|mailbox|1\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messages"))
+            .body(ARGUMENTS + ".list", empty());
+    }
+
+    @Test
+    public void setMessagesShouldReturnDestroyedNotDestroyWhenMixed() throws Exception {
+        jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test2\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test3\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        embeddedElasticSearch.awaitForElasticSearch();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + "|mailbox|1\", \"" + username + "|mailbox|4\", \"" + username + "|mailbox|3\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messagesSet"))
+            .body(ARGUMENTS + ".destroyed", hasSize(2))
+            .body(ARGUMENTS + ".notDestroyed", aMapWithSize(1))
+            .body(ARGUMENTS + ".destroyed", contains(username + "|mailbox|1", username + "|mailbox|3"))
+            .body(ARGUMENTS + ".notDestroyed", hasEntry(username + "|mailbox|4", 
+                    ImmutableMap.of("type", "notFound",
+                            "description", "The message " + username + "|mailbox|4 can't be found")));
+    }
+
+    @Test
+    public void setMessagesShouldDeleteMatchingMessagesWhenMixed() throws Exception {
+        // Given
+        jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test2\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        jmapServer.serverProbe().appendMessage(username, new MailboxPath(MailboxConstants.USER_NAMESPACE, username, "mailbox"), 
+                new ByteArrayInputStream("Subject: test3\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        embeddedElasticSearch.awaitForElasticSearch();
+
+        // When
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"setMessages\", {\"destroy\": [\"" + username + "|mailbox|1\", \"" + username + "|mailbox|4\", \"" + username + "|mailbox|3\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200);
+
+        // Then
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + username + "|mailbox|1\", \"" + username + "|mailbox|2\", \"" + username + "|mailbox|3\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messages"))
+            .body(ARGUMENTS + ".list", hasSize(1));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraSetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraSetMessagesMethodTest.java b/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraSetMessagesMethodTest.java
new file mode 100644
index 0000000..6d48f4b
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraSetMessagesMethodTest.java
@@ -0,0 +1,35 @@
+/****************************************************************
+ * 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.jmap.methods.cassandra;
+
+import org.apache.james.backends.cassandra.EmbeddedCassandra;
+import org.apache.james.jmap.JmapServer;
+import org.apache.james.jmap.cassandra.CassandraJmapServer;
+import org.apache.james.jmap.methods.SetMessagesMethodTest;
+import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
+import org.junit.rules.TemporaryFolder;
+
+public class CassandraSetMessagesMethodTest extends SetMessagesMethodTest {
+
+    @Override
+    protected JmapServer jmapServer(TemporaryFolder temporaryFolder, EmbeddedElasticSearch embeddedElasticSearch, EmbeddedCassandra cassandra) {
+        return new CassandraJmapServer(CassandraJmapServer.defaultOverrideModule(temporaryFolder, embeddedElasticSearch, cassandra));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MessageNotFoundException.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MessageNotFoundException.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MessageNotFoundException.java
new file mode 100644
index 0000000..6b09819
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/MessageNotFoundException.java
@@ -0,0 +1,23 @@
+/****************************************************************
+ * 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.jmap.exceptions;
+
+public class MessageNotFoundException extends Exception {
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesMethod.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesMethod.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesMethod.java
new file mode 100644
index 0000000..ebdaf77
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesMethod.java
@@ -0,0 +1,145 @@
+/****************************************************************
+ * 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.jmap.methods;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+
+import org.apache.james.jmap.exceptions.MessageNotFoundException;
+import org.apache.james.jmap.model.ClientId;
+import org.apache.james.jmap.model.MessageId;
+import org.apache.james.jmap.model.SetError;
+import org.apache.james.jmap.model.SetMessagesRequest;
+import org.apache.james.jmap.model.SetMessagesResponse;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MessageRange;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.mail.MailboxMapperFactory;
+import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxId;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+public class SetMessagesMethod<Id extends MailboxId> implements Method {
+
+    private static final int LIMIT_BY_ONE = 1;
+    private static final Logger LOGGER = LoggerFactory.getLogger(SetMessagesMethod.class);
+    private static final Method.Request.Name METHOD_NAME = Method.Request.name("setMessages");
+    private static final Method.Response.Name RESPONSE_NAME = Method.Response.name("messagesSet");
+
+    private final MailboxMapperFactory<Id> mailboxMapperFactory;
+    private final MailboxSessionMapperFactory<Id> mailboxSessionMapperFactory;
+
+    @Inject
+    @VisibleForTesting SetMessagesMethod(MailboxMapperFactory<Id> mailboxMapperFactory, MailboxSessionMapperFactory<Id> mailboxSessionMapperFactory) {
+        this.mailboxMapperFactory = mailboxMapperFactory;
+        this.mailboxSessionMapperFactory = mailboxSessionMapperFactory;
+    }
+
+    @Override
+    public Method.Request.Name requestHandled() {
+        return METHOD_NAME;
+    }
+
+    @Override
+    public Class<? extends JmapRequest> requestType() {
+        return SetMessagesRequest.class;
+    }
+
+    public Stream<JmapResponse> process(JmapRequest request, ClientId clientId, MailboxSession mailboxSession) {
+        Preconditions.checkArgument(request instanceof SetMessagesRequest);
+        try {
+            return Stream.of(
+                    JmapResponse.builder().clientId(clientId)
+                    .response(setMessagesResponse((SetMessagesRequest) request, mailboxSession))
+                    .responseName(RESPONSE_NAME)
+                    .build());
+        } catch (MailboxException e) {
+            return Stream.of(
+                    JmapResponse.builder().clientId(clientId)
+                    .error()
+                    .responseName(RESPONSE_NAME)
+                    .build());
+        }
+    }
+
+    private SetMessagesResponse setMessagesResponse(SetMessagesRequest request, MailboxSession mailboxSession) throws MailboxException {
+        SetMessagesResponse.Builder responseBuilder = SetMessagesResponse.builder();
+        processDestroy(request.getDestroy(), mailboxSession, responseBuilder);
+        return responseBuilder.build();
+    }
+
+    private void processDestroy(List<MessageId> messageIds, MailboxSession mailboxSession, SetMessagesResponse.Builder responseBuilder) throws MailboxException {
+        MessageMapper<Id> messageMapper = mailboxSessionMapperFactory.createMessageMapper(mailboxSession);
+        Consumer<? super MessageId> delete = delete(messageMapper, mailboxSession, responseBuilder);
+
+        messageIds.stream()
+            .forEach(delete);
+    }
+
+    private Consumer<? super MessageId> delete(MessageMapper<Id> messageMapper, MailboxSession mailboxSession, SetMessagesResponse.Builder responseBuilder) {
+        return (messageId) -> {
+            try {
+                Mailbox<Id> mailbox = mailboxMapperFactory
+                        .getMailboxMapper(mailboxSession)
+                        .findMailboxByPath(messageId.getMailboxPath(mailboxSession));
+
+                MailboxMessage<Id> mailboxMessage = getMailboxMessage(messageMapper, messageId, mailbox);
+
+                messageMapper.delete(mailbox, mailboxMessage);
+                responseBuilder.destroyed(messageId);
+            } catch (MessageNotFoundException e) {
+                responseBuilder.notDestroyed(messageId,
+                        SetError.builder()
+                        .type("notFound")
+                        .description("The message " + messageId.serialize() + " can't be found")
+                        .build());
+            } catch (MailboxException e) {
+                LOGGER.error("An error occurred when deleting a message", e);
+                responseBuilder.notDestroyed(messageId,
+                        SetError.builder()
+                        .type("anErrorOccurred")
+                        .description("An error occurred while deleting message " + messageId.serialize())
+                        .build());
+            }
+        };
+    }
+
+    private MailboxMessage<Id> getMailboxMessage(MessageMapper<Id> messageMapper, MessageId messageId, Mailbox<Id> mailbox) 
+            throws MailboxException, MessageNotFoundException {
+
+        Iterator<MailboxMessage<Id>> mailboxMessage = messageMapper.findInMailbox(mailbox, MessageRange.one(messageId.getUid()), FetchType.Metadata, LIMIT_BY_ONE);
+        if (!mailboxMessage.hasNext()) {
+            throw new MessageNotFoundException();
+        }
+        return mailboxMessage.next();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
index 6597111..b4b08c5 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
@@ -22,6 +22,7 @@ import java.util.Objects;
 
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSession.User;
+import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.javatuples.Triplet;
 
@@ -67,7 +68,7 @@ public class MessageId {
     }
     
     public MailboxPath getMailboxPath(MailboxSession mailboxSession) {
-        return new MailboxPath("", username, mailboxPath);
+        return new MailboxPath(MailboxConstants.USER_NAMESPACE, username, mailboxPath);
     }
     
     @JsonValue

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetError.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetError.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetError.java
new file mode 100644
index 0000000..da94af5
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetError.java
@@ -0,0 +1,80 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import java.util.Optional;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+
+@JsonDeserialize(builder = SetError.Builder.class)
+public class SetError {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @JsonPOJOBuilder(withPrefix = "")
+    public static class Builder {
+
+        private String type;
+        private String description;
+
+        private Builder() {
+        }
+
+        public Builder type(String type) {
+            this.type = type;
+            return this;
+        }
+
+        public Builder description(String description) {
+            this.description = description;
+            return this;
+        }
+
+        public SetError build() {
+            Preconditions.checkState(!Strings.isNullOrEmpty(type), "'type' is mandatory");
+            return new SetError(type, Optional.ofNullable(description));
+        }
+    }
+
+    private final String type;
+    private final Optional<String> description;
+
+    @VisibleForTesting SetError(String type, Optional<String> description) {
+        this.type = type;
+        this.description = description;
+    }
+
+    @JsonSerialize
+    public String getType() {
+        return type;
+    }
+
+    @JsonSerialize
+    public Optional<String> getDescription() {
+        return description;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java
new file mode 100644
index 0000000..9d6d158
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java
@@ -0,0 +1,126 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.jmap.methods.JmapRequest;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+
+@JsonDeserialize(builder = SetMessagesRequest.Builder.class)
+public class SetMessagesRequest implements JmapRequest {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @JsonPOJOBuilder(withPrefix = "")
+    public static class Builder {
+
+        private String accountId;
+        private String ifInState;
+        private ImmutableList.Builder<Message> create;
+        private ImmutableList.Builder<Message> update;
+        private ImmutableList.Builder<MessageId> destroy;
+
+        private Builder() {
+            create = ImmutableList.builder();
+            update = ImmutableList.builder();
+            destroy = ImmutableList.builder();
+        }
+
+        public Builder accountId(String accountId) {
+            if (accountId != null) {
+                throw new NotImplementedException();
+            }
+            return this;
+        }
+
+        public Builder ifInState(String ifInState) {
+            if (ifInState != null) {
+                throw new NotImplementedException();
+            }
+            return this;
+        }
+
+        public Builder create(List<Message> create) {
+            if (create != null && !create.isEmpty()) {
+                throw new NotImplementedException();
+            }
+            return this;
+        }
+
+        public Builder update(List<Message> update) {
+            if (update != null && !update.isEmpty()) {
+                throw new NotImplementedException();
+            }
+            return this;
+        }
+
+        public Builder destroy(List<MessageId> destroy) {
+            this.destroy.addAll(destroy);
+            return this;
+        }
+
+        public SetMessagesRequest build() {
+            return new SetMessagesRequest(Optional.ofNullable(accountId), Optional.ofNullable(ifInState), create.build(), update.build(), destroy.build());
+        }
+    }
+
+    private final Optional<String> accountId;
+    private final Optional<String> ifInState;
+    private final List<Message> create;
+    private final List<Message> update;
+    private final List<MessageId> destroy;
+
+    @VisibleForTesting SetMessagesRequest(Optional<String> accountId, Optional<String> ifInState, List<Message> create, List<Message> update, List<MessageId> destroy) {
+        this.accountId = accountId;
+        this.ifInState = ifInState;
+        this.create = create;
+        this.update = update;
+        this.destroy = destroy;
+    }
+
+    public Optional<String> getAccountId() {
+        return accountId;
+    }
+
+    public Optional<String> getIfInState() {
+        return ifInState;
+    }
+
+    public List<Message> getCreate() {
+        return create;
+    }
+
+    public List<Message> getUpdate() {
+        return update;
+    }
+
+    public List<MessageId> getDestroy() {
+        return destroy;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesResponse.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesResponse.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesResponse.java
new file mode 100644
index 0000000..67bdd46
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesResponse.java
@@ -0,0 +1,188 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.jmap.methods.Method;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+@JsonDeserialize(builder = SetMessagesResponse.Builder.class)
+public class SetMessagesResponse implements Method.Response {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @JsonPOJOBuilder(withPrefix = "")
+    public static class Builder {
+
+        private String accountId;
+        private String oldState;
+        private String newState;
+        private ImmutableList.Builder<Message> created;
+        private ImmutableList.Builder<MessageId> updated;
+        private ImmutableList.Builder<MessageId> destroyed;
+        private ImmutableMap.Builder<MessageId, SetError> notCreated;
+        private ImmutableMap.Builder<MessageId, SetError> notUpdated;
+        private ImmutableMap.Builder<MessageId, SetError> notDestroyed;
+
+        private Builder() {
+            created = ImmutableList.builder();
+            updated = ImmutableList.builder();
+            destroyed = ImmutableList.builder();
+            notCreated = ImmutableMap.builder();
+            notUpdated = ImmutableMap.builder();
+            notDestroyed = ImmutableMap.builder();
+        }
+
+        public Builder accountId(String accountId) {
+            throw new NotImplementedException();
+        }
+
+        public Builder oldState(String oldState) {
+            throw new NotImplementedException();
+        }
+
+        public Builder newState(String newState) {
+            throw new NotImplementedException();
+        }
+
+        public Builder created(List<Message> created) {
+            this.created.addAll(created);
+            return this;
+        }
+
+        public Builder updated(List<MessageId> updated) {
+            this.updated.addAll(updated);
+            return this;
+        }
+
+        public Builder destroyed(MessageId destroyed) {
+            this.destroyed.add(destroyed);
+            return this;
+        }
+
+        public Builder destroyed(List<MessageId> destroyed) {
+            this.destroyed.addAll(destroyed);
+            return this;
+        }
+
+        public Builder notCreated(Map<MessageId, SetError> notCreated) {
+            this.notCreated.putAll(notCreated);
+            return this;
+        }
+
+        public Builder notUpdated(Map<MessageId, SetError> notUpdated) {
+            this.notUpdated.putAll(notUpdated);
+            return this;
+        }
+
+        public Builder notDestroyed(MessageId messageId, SetError notDestroyed) {
+            this.notDestroyed.put(messageId, notDestroyed);
+            return this;
+        }
+
+        public Builder notDestroyed(Map<MessageId, SetError> notDestroyed) {
+            this.notDestroyed.putAll(notDestroyed);
+            return this;
+        }
+
+        public SetMessagesResponse build() {
+            return new SetMessagesResponse(accountId, oldState, newState, 
+                    created.build(), updated.build(), destroyed.build(), notCreated.build(), notUpdated.build(), notDestroyed.build());
+        }
+    }
+
+    private final String accountId;
+    private final String oldState;
+    private final String newState;
+    private final List<Message> created;
+    private final List<MessageId> updated;
+    private final List<MessageId> destroyed;
+    private final Map<MessageId, SetError> notCreated;
+    private final Map<MessageId, SetError> notUpdated;
+    private final Map<MessageId, SetError> notDestroyed;
+
+    @VisibleForTesting SetMessagesResponse(String accountId, String oldState, String newState, List<Message> created, List<MessageId> updated, List<MessageId> destroyed, 
+            Map<MessageId, SetError> notCreated, Map<MessageId, SetError> notUpdated, Map<MessageId, SetError> notDestroyed) {
+        this.accountId = accountId;
+        this.oldState = oldState;
+        this.newState = newState;
+        this.created = created;
+        this.updated = updated;
+        this.destroyed = destroyed;
+        this.notCreated = notCreated;
+        this.notUpdated = notUpdated;
+        this.notDestroyed = notDestroyed;
+    }
+
+    @JsonSerialize
+    public String getAccountId() {
+        return accountId;
+    }
+
+    @JsonSerialize
+    public String getOldState() {
+        return oldState;
+    }
+
+    @JsonSerialize
+    public String getNewState() {
+        return newState;
+    }
+
+    @JsonSerialize
+    public List<Message> getCreated() {
+        return created;
+    }
+
+    @JsonSerialize
+    public List<MessageId> getUpdated() {
+        return updated;
+    }
+
+    @JsonSerialize
+    public List<MessageId> getDestroyed() {
+        return destroyed;
+    }
+
+    @JsonSerialize
+    public Map<MessageId, SetError> getNotCreated() {
+        return notCreated;
+    }
+
+    @JsonSerialize
+    public Map<MessageId, SetError> getNotUpdated() {
+        return notUpdated;
+    }
+
+    @JsonSerialize
+    public Map<MessageId, SetError> getNotDestroyed() {
+        return notDestroyed;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetErrorTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetErrorTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetErrorTest.java
new file mode 100644
index 0000000..1d5ace1
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetErrorTest.java
@@ -0,0 +1,59 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Optional;
+
+import org.junit.Test;
+
+public class SetErrorTest {
+
+    @Test
+    public void buildShouldThrowWhenTypeIsNotGiven() {
+        assertThatThrownBy(() -> SetError.builder().build())
+            .isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void buildShouldWorkWhenAllMandatoryFieldsAreGiven() {
+        SetError expected = new SetError("type", Optional.empty());
+
+        SetError setError = SetError.builder()
+            .type("type")
+            .build();
+
+        assertThat(setError).isEqualToComparingFieldByField(expected);
+    }
+
+    @Test
+    public void buildShouldWorkWhenAllFieldsAreGiven() {
+        SetError expected = new SetError("type", Optional.of("description"));
+
+        SetError setError = SetError.builder()
+            .type("type")
+            .description("description")
+            .build();
+
+        assertThat(setError).isEqualToComparingFieldByField(expected);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesRequestTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesRequestTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesRequestTest.java
new file mode 100644
index 0000000..b600172
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesRequestTest.java
@@ -0,0 +1,96 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.time.ZonedDateTime;
+import java.util.Optional;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class SetMessagesRequestTest {
+
+    @Test
+    public void builderShouldThrowWhenAccountIdIsNotNull() {
+        assertThatThrownBy(() -> SetMessagesRequest.builder().accountId(""))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenIfInStateIsNotNull() {
+        assertThatThrownBy(() -> SetMessagesRequest.builder().ifInState(""))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenCreateIsNotEmpty() {
+        assertThatThrownBy(() -> SetMessagesRequest.builder().create(ImmutableList.of(Message.builder()
+                .id(MessageId.of("user|create|1"))
+                .blobId("blobId")
+                .threadId("threadId")
+                .mailboxIds(ImmutableList.of("mailboxId"))
+                .headers(ImmutableMap.of("key", "value"))
+                .subject("subject")
+                .size(123)
+                .date(ZonedDateTime.now())
+                .preview("preview")
+                .build())))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenUpdateIsNotEmpty() {
+        assertThatThrownBy(() -> SetMessagesRequest.builder().update(ImmutableList.of(Message.builder()
+                .id(MessageId.of("user|create|1"))
+                .blobId("blobId")
+                .threadId("threadId")
+                .mailboxIds(ImmutableList.of("mailboxId"))
+                .headers(ImmutableMap.of("key", "value"))
+                .subject("subject")
+                .size(123)
+                .date(ZonedDateTime.now())
+                .preview("preview")
+                .build())))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldWork() {
+        ImmutableList<MessageId> destroy = ImmutableList.of(MessageId.of("user|destroy|1"));
+
+        SetMessagesRequest expected = new SetMessagesRequest(Optional.empty(), Optional.empty(), ImmutableList.of(), ImmutableList.of(), destroy);
+
+        SetMessagesRequest setMessagesRequest = SetMessagesRequest.builder()
+            .accountId(null)
+            .ifInState(null)
+            .create(ImmutableList.of())
+            .update(ImmutableList.of())
+            .destroy(destroy)
+            .build();
+
+        assertThat(setMessagesRequest).isEqualToComparingFieldByField(expected);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6665a49e/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesResponseTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesResponseTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesResponseTest.java
new file mode 100644
index 0000000..23743f3
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetMessagesResponseTest.java
@@ -0,0 +1,86 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.time.ZonedDateTime;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class SetMessagesResponseTest {
+
+    @Test
+    public void builderShouldThrowWhenAccountIdIsGiven() {
+        assertThatThrownBy(() -> SetMessagesResponse.builder().accountId(""))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenOldStateGiven() {
+        assertThatThrownBy(() -> SetMessagesResponse.builder().oldState(""))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenNewStateIsGiven() {
+        assertThatThrownBy(() -> SetMessagesResponse.builder().newState(""))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void builderShouldWork() {
+        ZonedDateTime currentDate = ZonedDateTime.now();
+        ImmutableList<Message> created = ImmutableList.of(
+            Message.builder()
+                .id(MessageId.of("user|created|1"))
+                .blobId("blobId")
+                .threadId("threadId")
+                .mailboxIds(ImmutableList.of("mailboxId"))
+                .headers(ImmutableMap.of("key", "value"))
+                .subject("subject")
+                .size(123)
+                .date(currentDate)
+                .preview("preview")
+                .build());
+        ImmutableList<MessageId> updated = ImmutableList.of(MessageId.of("user|updated|1"));
+        ImmutableList<MessageId> destroyed = ImmutableList.of(MessageId.of("user|destroyed|1"));
+        ImmutableMap<MessageId, SetError> notCreated = ImmutableMap.of(MessageId.of("user|created|2"), SetError.builder().type("created").build());
+        ImmutableMap<MessageId, SetError> notUpdated = ImmutableMap.of(MessageId.of("user|update|2"), SetError.builder().type("updated").build());
+        ImmutableMap<MessageId, SetError> notDestroyed  = ImmutableMap.of(MessageId.of("user|destroyed|3"), SetError.builder().type("destroyed").build());
+        SetMessagesResponse expected = new SetMessagesResponse(null, null, null, created, updated, destroyed, notCreated, notUpdated, notDestroyed);
+
+        SetMessagesResponse setMessagesResponse = SetMessagesResponse.builder()
+            .created(created)
+            .updated(updated)
+            .destroyed(destroyed)
+            .notCreated(notCreated)
+            .notUpdated(notUpdated)
+            .notDestroyed(notDestroyed)
+            .build();
+
+        assertThat(setMessagesResponse).isEqualToComparingFieldByField(expected);
+    }
+}


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


Mime
View raw message