You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2017/08/25 08:32:45 UTC
[07/13] james-project git commit: JAMES-2110 IT for setMessage with
keywords
JAMES-2110 IT for setMessage with keywords
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/37cf8ffc
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/37cf8ffc
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/37cf8ffc
Branch: refs/heads/master
Commit: 37cf8ffc389219c55793dffc5692f898dad331b1
Parents: a6f1c10
Author: quynhn <qn...@linagora.com>
Authored: Tue Aug 15 16:46:53 2017 +0700
Committer: Raphael Ouazana <ra...@linagora.com>
Committed: Thu Aug 24 15:47:28 2017 +0200
----------------------------------------------------------------------
.../james/mailbox/store/probe/MailboxProbe.java | 2 +-
.../james/cli/probe/impl/JmxMailboxProbe.java | 9 +-
.../apache/james/modules/MailboxProbeImpl.java | 6 +-
.../modules/protocols/JMAPServerModule.java | 2 +
.../org/apache/james/utils/MessageIdProbe.java | 50 ++
.../integration/SetMessagesMethodTest.java | 587 +++++++++++++++++--
6 files changed, 593 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/37cf8ffc/mailbox/store/src/main/java/org/apache/james/mailbox/store/probe/MailboxProbe.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/probe/MailboxProbe.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/probe/MailboxProbe.java
index 6878bb5..b96671e 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/probe/MailboxProbe.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/probe/MailboxProbe.java
@@ -41,7 +41,7 @@ public interface MailboxProbe {
void deleteMailbox(String namespace, String user, String name);
void importEmlFileToMailbox(String namespace, String user, String name, String emlpath) throws Exception;
-
+
ComposedMessageId appendMessage(String username, MailboxPath mailboxPath, InputStream message, Date internalDate,
boolean isRecent, Flags flags) throws MailboxException;
http://git-wip-us.apache.org/repos/asf/james-project/blob/37cf8ffc/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxMailboxProbe.java
----------------------------------------------------------------------
diff --git a/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxMailboxProbe.java b/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxMailboxProbe.java
index b3b5cc5..ab9005a 100644
--- a/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxMailboxProbe.java
+++ b/server/container/cli/src/main/java/org/apache/james/cli/probe/impl/JmxMailboxProbe.java
@@ -23,7 +23,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Date;
-
import javax.mail.Flags;
import javax.management.MalformedObjectNameException;
@@ -37,15 +36,15 @@ import org.apache.james.mailbox.store.mail.model.Mailbox;
import org.apache.james.mailbox.store.probe.MailboxProbe;
public class JmxMailboxProbe implements MailboxProbe, JmxProbe {
-
+
private final static String MAILBOXCOPIER_OBJECT_NAME = "org.apache.james:type=component,name=mailboxcopier";
private final static String MAILBOXMANAGER_OBJECT_NAME = "org.apache.james:type=component,name=mailboxmanagerbean";
private final static String REINDEXER_OBJECT_NAME = "org.apache.james:type=component,name=reindexerbean";
-
+
private MailboxCopierManagementMBean mailboxCopierManagement;
private MailboxManagerManagementMBean mailboxManagerManagement;
private ReIndexerManagementMBean reIndexerManagement;
-
+
public JmxMailboxProbe connect(JmxConnection jmxc) throws IOException {
try {
mailboxCopierManagement = jmxc.retrieveBean(MailboxCopierManagementMBean.class, MAILBOXCOPIER_OBJECT_NAME);
@@ -56,7 +55,7 @@ public class JmxMailboxProbe implements MailboxProbe, JmxProbe {
}
return this;
}
-
+
@Override
public void copyMailbox(String srcBean, String dstBean) throws Exception {
http://git-wip-us.apache.org/repos/asf/james-project/blob/37cf8ffc/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
----------------------------------------------------------------------
diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
index 73982a7..6dbfb05 100644
--- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
+++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/MailboxProbeImpl.java
@@ -155,11 +155,11 @@ public class MailboxProbeImpl implements GuiceProbe, MailboxProbe {
mailboxManager.endProcessingRequest(mailboxSession);
mailboxSession.close();
}
-
+
@Override
- public ComposedMessageId appendMessage(String username, MailboxPath mailboxPath, InputStream message, Date internalDate, boolean isRecent, Flags flags)
+ public ComposedMessageId appendMessage(String username, MailboxPath mailboxPath, InputStream message, Date internalDate, boolean isRecent, Flags flags)
throws MailboxException {
-
+
MailboxSession mailboxSession = mailboxManager.createSystemSession(username);
MessageManager messageManager = mailboxManager.getMailbox(mailboxPath, mailboxSession);
return messageManager.appendMessage(message, internalDate, mailboxSession, isRecent, flags);
http://git-wip-us.apache.org/repos/asf/james-project/blob/37cf8ffc/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
index aa1cc00..c601c44 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/modules/protocols/JMAPServerModule.java
@@ -26,6 +26,7 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.james.jmap.JMAPConfiguration;
import org.apache.james.jmap.JMAPModule;
import org.apache.james.jmap.JMAPServer;
+import org.apache.james.utils.MessageIdProbe;
import org.apache.james.jmap.crypto.JamesSignatureHandler;
import org.apache.james.lifecycle.api.Configurable;
import org.apache.james.utils.ConfigurationPerformer;
@@ -49,6 +50,7 @@ public class JMAPServerModule extends AbstractModule {
install(new JMAPModule());
Multibinder.newSetBinder(binder(), ConfigurationPerformer.class).addBinding().to(JMAPModuleConfigurationPerformer.class);
Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(JmapGuiceProbe.class);
+ Multibinder.newSetBinder(binder(), GuiceProbe.class).addBinding().to(MessageIdProbe.class);
}
@Singleton
http://git-wip-us.apache.org/repos/asf/james-project/blob/37cf8ffc/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/MessageIdProbe.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/MessageIdProbe.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/MessageIdProbe.java
new file mode 100644
index 0000000..f6b97a2
--- /dev/null
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/utils/MessageIdProbe.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.utils;
+
+import java.util.List;
+import javax.inject.Inject;
+
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageIdManager;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.FetchGroupImpl;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.MessageResult;
+
+import com.google.common.collect.ImmutableList;
+
+public class MessageIdProbe implements GuiceProbe {
+ private final MailboxManager mailboxManager;
+ private final MessageIdManager messageIdManager;
+
+ @Inject
+ public MessageIdProbe(MailboxManager mailboxManager, MessageIdManager messageIdManager) {
+ this.mailboxManager = mailboxManager;
+ this.messageIdManager = messageIdManager;
+ }
+
+ public List<MessageResult> getMessages(MessageId messageId, String user) throws MailboxException {
+ MailboxSession mailboxSession = mailboxManager.createSystemSession(user);
+
+ return messageIdManager.getMessages(ImmutableList.of(messageId), FetchGroupImpl.FULL_CONTENT, mailboxSession);
+ }
+}
http://git-wip-us.apache.org/repos/asf/james-project/blob/37cf8ffc/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
index f372583..3fe34bb 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
@@ -26,6 +26,7 @@ import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
@@ -38,7 +39,6 @@ import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
import static org.hamcrest.collection.IsMapWithSize.anEmptyMap;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.time.ZonedDateTime;
@@ -47,16 +47,15 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-
import javax.mail.Flags;
+import javax.mail.Flags.Flag;
-import org.apache.commons.io.IOUtils;
-import org.apache.http.client.utils.URIBuilder;
import org.apache.james.GuiceJamesServer;
import org.apache.james.jmap.DefaultMailboxes;
import org.apache.james.jmap.HttpJmapAuthentication;
import org.apache.james.jmap.api.access.AccessToken;
import org.apache.james.jmap.model.mailbox.Role;
+import org.apache.james.mailbox.FlagsBuilder;
import org.apache.james.mailbox.MailboxListener;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.Attachment;
@@ -64,20 +63,18 @@ import org.apache.james.mailbox.model.ComposedMessageId;
import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.MessageResult;
import org.apache.james.mailbox.store.event.EventFactory;
import org.apache.james.mailbox.store.mail.model.Mailbox;
import org.apache.james.mailbox.store.probe.MailboxProbe;
import org.apache.james.modules.MailboxProbeImpl;
+import org.apache.james.utils.MessageIdProbe;
import org.apache.james.probe.DataProbe;
import org.apache.james.util.ZeroedInputStream;
-import org.apache.james.utils.JmapGuiceProbe;
import org.apache.james.utils.DataProbeImpl;
-import org.hamcrest.Matcher;
-import org.hamcrest.Matchers;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
+import org.apache.james.utils.JmapGuiceProbe;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.client.utils.URIBuilder;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
@@ -91,9 +88,16 @@ import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.builder.ResponseSpecBuilder;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.specification.ResponseSpecification;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
public abstract class SetMessagesMethodTest {
+ private final static String FORWARDED = "$Forwarded";
private static final int _1MB = 1024*1024;
private static final String NAME = "[0][0]";
private static final String ARGUMENTS = "[0][1]";
@@ -103,27 +107,30 @@ public abstract class SetMessagesMethodTest {
private static final String USERNAME = "username@" + USERS_DOMAIN;
public static final MailboxPath USER_MAILBOX = new MailboxPath(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
private static final String NOT_UPDATED = ARGUMENTS + ".notUpdated";
+ private static final String NOT_CREATED = ARGUMENTS + ".notCreated";
private ConditionFactory calmlyAwait;
protected abstract GuiceJamesServer createJmapServer();
protected abstract MessageId randomMessageId();
-
+
protected abstract void await();
private AccessToken accessToken;
private GuiceJamesServer jmapServer;
private MailboxProbe mailboxProbe;
private DataProbe dataProbe;
-
+ private MessageIdProbe messageProbe;
+
@Before
public void setup() throws Throwable {
jmapServer = createJmapServer();
jmapServer.start();
mailboxProbe = jmapServer.getProbe(MailboxProbeImpl.class);
dataProbe = jmapServer.getProbe(DataProbeImpl.class);
-
+ messageProbe = jmapServer.getProbe(MessageIdProbe.class);
+
RestAssured.requestSpecification = new RequestSpecBuilder()
.setContentType(ContentType.JSON)
.setAccept(ContentType.JSON)
@@ -161,7 +168,7 @@ public abstract class SetMessagesMethodTest {
public void teardown() {
jmapServer.stop();
}
-
+
private String getOutboxId(AccessToken accessToken) {
return getMailboxId(accessToken, Role.OUTBOX);
}
@@ -172,7 +179,7 @@ public abstract class SetMessagesMethodTest {
.map(x -> x.get("id"))
.findFirst().get();
}
-
+
private List<Map<String, String>> getAllMailboxesIds(AccessToken accessToken) {
return with()
.header("Authorization", accessToken.serialize())
@@ -185,7 +192,7 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessagesShouldReturnErrorNotSupportedWhenRequestContainsNonNullAccountId() throws Exception {
+ public void setMessagesShouldReturnAnErrorNotSupportedWhenRequestContainsNonNullAccountId() throws Exception {
given()
.header("Authorization", accessToken.serialize())
.body("[[\"setMessages\", {\"accountId\": \"1\"}, \"#0\"]]")
@@ -199,7 +206,7 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessagesShouldReturnErrorNotSupportedWhenRequestContainsNonNullIfInState() throws Exception {
+ public void setMessagesShouldReturnAnErrorNotSupportedWhenRequestContainsNonNullIfInState() throws Exception {
given()
.header("Authorization", accessToken.serialize())
.body("[[\"setMessages\", {\"ifInState\": \"1\"}, \"#0\"]]")
@@ -369,7 +376,7 @@ public abstract class SetMessagesMethodTest {
randomMessageId().serialize(),
message3.getMessageId().serialize()))
.post("/jmap");
-
+
// Then
given()
.header("Authorization", accessToken.serialize())
@@ -396,7 +403,7 @@ public abstract class SetMessagesMethodTest {
await();
String serializedMessageId = message.getMessageId().serialize();
-
+
// When
given()
.header("Authorization", accessToken.serialize())
@@ -409,6 +416,322 @@ public abstract class SetMessagesMethodTest {
.spec(getSetMessagesUpdateOKResponseAssertions(serializedMessageId));
}
+ @Test
+ public void setMessagesWithUpdateShouldReturnAnErrorWhenBothIsFlagAndKeywordsArePassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags());
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"isUnread\" : false, \"keywords\": {\"$Seen\": true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .body(NOT_UPDATED, hasKey(messageId))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].type", equalTo("invalidProperties"))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].description", containsString("Does not support keyword and is* at the same time"))
+ .body(ARGUMENTS + ".updated", hasSize(0));
+ }
+
+ @Test
+ public void setMessagesShouldUpdateKeywordsWhenKeywordsArePassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags());
+ await();
+
+ String serializedMessageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Seen\": true, \"$Flagged\": true} } } }, \"#0\"]]", serializedMessageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .spec(getSetMessagesUpdateOKResponseAssertions(serializedMessageId));
+
+ with()
+ .header("Authorization", accessToken.serialize())
+ .body("[[\"getMessages\", {\"ids\": [\"" + serializedMessageId + "\"]}, \"#0\"]]")
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("messages"))
+ .body(ARGUMENTS + ".list", hasSize(1))
+ .body(ARGUMENTS + ".list[0].keywords.$Seen", equalTo(true))
+ .body(ARGUMENTS + ".list[0].keywords.$Flagged", equalTo(true));
+ }
+
+ @Test
+ public void setMessagesShouldAddForwardedFlagWhenKeywordsWithForwardedIsPassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags());
+ await();
+
+ String serializedMessageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Seen\": true, \"$Forwarded\": true} } } }, \"#0\"]]", serializedMessageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .spec(getSetMessagesUpdateOKResponseAssertions(serializedMessageId));
+
+ with()
+ .header("Authorization", accessToken.serialize())
+ .body("[[\"getMessages\", {\"ids\": [\"" + serializedMessageId + "\"]}, \"#0\"]]")
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("messages"))
+ .body(ARGUMENTS + ".list", hasSize(1))
+ .body(ARGUMENTS + ".list[0].keywords.$Seen", equalTo(true))
+ .body(ARGUMENTS + ".list[0].keywords.$Forwarded", equalTo(true));
+ }
+
+ @Test
+ public void setMessagesShouldRemoveForwardedFlagWhenKeywordsWithoutForwardedIsPassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ Flags flags = FlagsBuilder.builder()
+ .add(Flag.SEEN)
+ .add(FORWARDED)
+ .build();
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, flags);
+ await();
+
+ String serializedMessageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Seen\": true} } } }, \"#0\"]]", serializedMessageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .spec(getSetMessagesUpdateOKResponseAssertions(serializedMessageId));
+
+ with()
+ .header("Authorization", accessToken.serialize())
+ .body("[[\"getMessages\", {\"ids\": [\"" + serializedMessageId + "\"]}, \"#0\"]]")
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("messages"))
+ .body(ARGUMENTS + ".list", hasSize(1))
+ .body(ARGUMENTS + ".list[0].keywords.$Seen", equalTo(true));
+ }
+
+ @Test
+ public void setMessagesShouldReturnAnErrorWhenKeywordsWithAddingDraftArePassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags(Flags.Flag.ANSWERED));
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Draft\": true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .body(NOT_UPDATED, hasKey(messageId))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].type", equalTo("invalidProperties"))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].properties[0]", equalTo("keywords"))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].description", equalTo("keywords: Cannot add or remove draft flag"))
+ .body(ARGUMENTS + ".updated", hasSize(0));
+ }
+
+ @Test
+ public void setMessagesShouldReturnAnErrorWhenKeywordsWithDeletedArePassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags(Flags.Flag.ANSWERED));
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Answered\": true, \"$Deleted\" : true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .body(NOT_UPDATED, hasKey(messageId))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].type", equalTo("invalidProperties"))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].description", containsString("Does not allow to update 'Deleted' or 'Recent' flag"))
+ .body(ARGUMENTS + ".updated", hasSize(0));
+ }
+
+ @Test
+ public void setMessagesShouldReturnAnErrorWhenKeywordsWithRecentArePassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags(Flags.Flag.ANSWERED));
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Answered\": true, \"$Recent\": true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .body(NOT_UPDATED, hasKey(messageId))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].type", equalTo("invalidProperties"))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].description", containsString("Does not allow to update 'Deleted' or 'Recent' flag"))
+ .body(ARGUMENTS + ".updated", hasSize(0));
+ }
+
+ @Test
+ public void setMessagesShouldNotChangeOriginDeletedFlag() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags(Flags.Flag.DELETED));
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Answered\": true, \"$Forwarded\": true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .spec(getSetMessagesUpdateOKResponseAssertions(messageId));
+
+ List<MessageResult> messages = messageProbe.getMessages(message.getMessageId(), USERNAME);
+ Flags expectedFlags = FlagsBuilder.builder()
+ .add(Flag.ANSWERED, Flag.DELETED)
+ .add(FORWARDED)
+ .build();
+
+ assertThat(messages)
+ .hasSize(1)
+ .extracting(MessageResult::getFlags)
+ .containsOnly(expectedFlags);
+ }
+
+ @Test
+ public void setMessagesShouldNotChangeOriginRecentFlag() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+ Flags flags = FlagsBuilder.builder()
+ .add(Flag.DELETED, Flag.RECENT)
+ .build();
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, flags);
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Answered\": true, \"$Forwarded\": true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .spec(getSetMessagesUpdateOKResponseAssertions(messageId));
+
+ List<MessageResult> messages = messageProbe.getMessages(message.getMessageId(), USERNAME);
+
+ Flags expectedFlags = FlagsBuilder.builder()
+ .add(Flag.ANSWERED, Flag.DELETED, Flag.RECENT)
+ .add(FORWARDED)
+ .build();
+
+ assertThat(messages)
+ .hasSize(1)
+ .extracting(MessageResult::getFlags)
+ .containsOnly(expectedFlags);
+ }
+
+ @Test
+ public void setMessagesShouldReturnAnErrorWhenKeywordsWithRemoveDraftArePassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags(Flags.Flag.DRAFT));
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .body(NOT_UPDATED, hasKey(messageId))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].type", equalTo("invalidProperties"))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].properties[0]", equalTo("keywords"))
+ .body(NOT_UPDATED + "[\""+messageId+"\"].description", equalTo("keywords: Cannot add or remove draft flag"))
+ .body(ARGUMENTS + ".updated", hasSize(0));
+ }
+
+ @Test
+ public void setMessagesShouldReturnNewKeywordsWhenKeywordsArePassedToRemoveAndAddFlag() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ Flags currentFlags = FlagsBuilder.builder()
+ .add(Flag.DRAFT, Flag.ANSWERED)
+ .build();
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, currentFlags);
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Draft\": true, \"$Flagged\": true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .spec(getSetMessagesUpdateOKResponseAssertions(messageId));
+
+ with()
+ .header("Authorization", accessToken.serialize())
+ .body("[[\"getMessages\", {\"ids\": [\"" + messageId + "\"]}, \"#0\"]]")
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("messages"))
+ .body(ARGUMENTS + ".list", hasSize(1))
+ .body(ARGUMENTS + ".list[0].keywords.$Draft", equalTo(true))
+ .body(ARGUMENTS + ".list[0].keywords.$Flagged", equalTo(true));
+ }
+
private ResponseSpecification getSetMessagesUpdateOKResponseAssertions(String messageId) {
ResponseSpecBuilder builder = new ResponseSpecBuilder()
.expectStatusCode(200)
@@ -656,7 +979,7 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessageShouldReturnNotFoundWhenUpdateUnknownMessage() {
+ public void setMessagesShouldReturnNotFoundWhenUpdateUnknownMessage() {
mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
String nonExistingMessageId = randomMessageId().serialize();
@@ -677,7 +1000,7 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessageShouldReturnCreatedMessageWhenSendingMessage() {
+ public void setMessagesShouldReturnCreatedMessageWhenSendingMessage() {
String messageCreationId = "creationId1337";
String fromAddress = USERNAME;
String requestBody = "[" +
@@ -717,10 +1040,10 @@ public abstract class SetMessagesMethodTest {
hasEntry(equalTo("threadId"), not(isEmptyOrNullString())),
hasEntry(equalTo("size"), not(isEmptyOrNullString()))
)))
- // assert that message flags are all unset
+ // assert that message FLAGS are all unset
.body(ARGUMENTS + ".created", hasEntry(equalTo(messageCreationId), Matchers.allOf(
hasEntry(equalTo("isDraft"), equalTo(false)),
- hasEntry(equalTo("isUnread"), equalTo(false)),
+ hasEntry(equalTo("isUnread"), equalTo(true)),
hasEntry(equalTo("isFlagged"), equalTo(false)),
hasEntry(equalTo("isAnswered"), equalTo(false))
)))
@@ -728,7 +1051,7 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessageShouldReturnCreatedMessageWithEmptySubjectWhenSubjectIsNull() {
+ public void setMessagesShouldReturnCreatedMessageWithEmptySubjectWhenSubjectIsNull() {
String messageCreationId = "creationId1337";
String fromAddress = USERNAME;
String requestBody = "[" +
@@ -762,7 +1085,7 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessageShouldReturnCreatedMessageWithEmptySubjectWhenSubjectIsEmpty() {
+ public void setMessagesShouldReturnCreatedMessageWithEmptySubjectWhenSubjectIsEmpty() {
String messageCreationId = "creationId1337";
String fromAddress = USERNAME;
String requestBody = "[" +
@@ -794,9 +1117,9 @@ public abstract class SetMessagesMethodTest {
.body(ARGUMENTS + ".created", hasKey(messageCreationId))
.body(ARGUMENTS + ".created[\""+messageCreationId+"\"].subject", equalTo(""));
}
-
+
@Test
- public void setMessageShouldReturnCreatedMessageWithNonASCIICharactersInSubjectWhenPresent() {
+ public void setMessagesShouldReturnCreatedMessageWithNonASCIICharactersInSubjectWhenPresent() {
String messageCreationId = "creationId1337";
String fromAddress = USERNAME;
String requestBody = "[" +
@@ -830,7 +1153,77 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessageShouldSupportArbitraryMessageId() {
+ public void setMessageWithCreatedMessageShouldReturnAnErrorWhenBothIsFlagAndKeywordsPresent() {
+ String messageCreationId = "creationId1337";
+ String fromAddress = USERNAME;
+ String requestBody = "[" +
+ " [" +
+ " \"setMessages\","+
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}," +
+ " \"to\": [{ \"name\": \"BOB\", \"email\": \"someone@example.com\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"isDraft\": true," +
+ " \"keywords\": {\"$Draft\": true}," +
+ " \"mailboxIds\": [\"" + getOutboxId(accessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(requestBody)
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("error"))
+ .body(ARGUMENTS + ".type", equalTo("invalidArguments"))
+ .body(ARGUMENTS + ".description", containsString("Does not support keyword and is* at the same time"));
+ }
+
+ @Test
+ public void setMessageWithCreatedMessageShouldSupportKeywordsForFlags() {
+ String messageCreationId = "creationId1337";
+ String fromAddress = USERNAME;
+ String requestBody = "[" +
+ " [" +
+ " \"setMessages\","+
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}," +
+ " \"to\": [{ \"name\": \"BOB\", \"email\": \"someone@example.com\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"keywords\": {\"$Draft\": true, \"$Flagged\": true}," +
+ " \"mailboxIds\": [\"" + getOutboxId(accessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(requestBody)
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("messagesSet"))
+ .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
+ .body(ARGUMENTS + ".created", aMapWithSize(1))
+ .body(ARGUMENTS + ".created", hasKey(messageCreationId))
+ .body(ARGUMENTS + ".created[\""+messageCreationId+"\"].keywords.$Draft", equalTo(true))
+ .body(ARGUMENTS + ".created[\""+messageCreationId+"\"].keywords.$Flagged", equalTo(true))
+ ;
+ }
+ @Test
+ public void setMessagesShouldSupportArbitraryMessageId() {
String messageCreationId = "1717fcd1-603e-44a5-b2a6-1234dbcd5723";
String fromAddress = USERNAME;
String requestBody = "[" +
@@ -1325,7 +1718,7 @@ public abstract class SetMessagesMethodTest {
.log().ifValidationFails()
.statusCode(200)
.body(SECOND_NAME, equalTo("messages"))
- .body(SECOND_ARGUMENTS + ".list", hasSize(1))
+ .body(SECOND_ARGUMENTS + ".list", hasSize(1))
.body(SECOND_ARGUMENTS + ".list[0].bcc", empty());
}
@@ -1380,7 +1773,7 @@ public abstract class SetMessagesMethodTest {
.log().ifValidationFails()
.statusCode(200)
.body(SECOND_NAME, equalTo("messages"))
- .body(SECOND_ARGUMENTS + ".list", hasSize(1))
+ .body(SECOND_ARGUMENTS + ".list", hasSize(1))
.body(SECOND_ARGUMENTS + ".list[0].bcc", hasSize(1));
}
@@ -1439,7 +1832,7 @@ public abstract class SetMessagesMethodTest {
.log().ifValidationFails()
.statusCode(200)
.body(SECOND_NAME, equalTo("messages"))
- .body(SECOND_ARGUMENTS + ".list", hasSize(1))
+ .body(SECOND_ARGUMENTS + ".list", hasSize(1))
.body(SECOND_ARGUMENTS + ".list[0].bcc", empty());
}
@@ -1455,7 +1848,7 @@ public abstract class SetMessagesMethodTest {
.body(NAME, equalTo("messageList"))
.body(ARGUMENTS + ".messageIds", hasSize(1));
return true;
-
+
} catch (AssertionError e) {
return false;
}
@@ -1591,7 +1984,7 @@ public abstract class SetMessagesMethodTest {
.body(ARGUMENTS + ".created", aMapWithSize(0));
}
-
+
private boolean isHtmlMessageReceived(AccessToken recipientToken) {
try {
with()
@@ -1609,7 +2002,7 @@ public abstract class SetMessagesMethodTest {
return false;
}
}
-
+
@Test
public void setMessagesShouldSendAReadableTextPlusHtmlMessage() throws Exception {
// Recipient
@@ -2152,7 +2545,7 @@ public abstract class SetMessagesMethodTest {
.body(ARGUMENTS + ".list", hasSize(1))
.body(firstMessage + ".mailboxIds", containsInAnyOrder(trashId, mailboxId));
}
-
+
@Test
public void setMessagesShouldReturnAttachmentsNotFoundWhenBlobIdDoesntExist() throws Exception {
String messageCreationId = "creationId";
@@ -2430,7 +2823,7 @@ public abstract class SetMessagesMethodTest {
String thirdAttachment = message + ".attachments[2]";
String inboxId = getMailboxId(accessToken, Role.INBOX);
- String receivedMessageId =
+ String receivedMessageId =
with()
.header("Authorization", accessToken.serialize())
.body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + inboxId + "\"]}}, \"#0\"]]")
@@ -2438,7 +2831,7 @@ public abstract class SetMessagesMethodTest {
.then()
.extract()
.path(ARGUMENTS + ".messageIds[0]");
-
+
given()
.header("Authorization", accessToken.serialize())
.body("[[\"getMessages\", {\"ids\": [\"" + receivedMessageId + "\"]}, \"#0\"]]")
@@ -2479,7 +2872,7 @@ public abstract class SetMessagesMethodTest {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127};
-
+
Attachment attachment = Attachment.builder()
.bytes(rawBytes)
.type("application/octet-stream")
@@ -2521,7 +2914,7 @@ public abstract class SetMessagesMethodTest {
calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken));
String inboxId = getMailboxId(accessToken, Role.INBOX);
- String receivedMessageId =
+ String receivedMessageId =
with()
.header("Authorization", accessToken.serialize())
.body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + inboxId + "\"]}}, \"#0\"]]")
@@ -2529,7 +2922,7 @@ public abstract class SetMessagesMethodTest {
.then()
.extract()
.path(ARGUMENTS + ".messageIds[0]");
-
+
String firstMessage = ARGUMENTS + ".list[0]";
String firstAttachment = firstMessage + ".attachments[0]";
given()
@@ -2593,7 +2986,7 @@ public abstract class SetMessagesMethodTest {
calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken));
String inboxId = getMailboxId(accessToken, Role.INBOX);
- String receivedMessageId =
+ String receivedMessageId =
with()
.header("Authorization", accessToken.serialize())
.body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + inboxId + "\"]}}, \"#0\"]]")
@@ -2601,7 +2994,7 @@ public abstract class SetMessagesMethodTest {
.then()
.extract()
.path(ARGUMENTS + ".messageIds[0]");
-
+
String firstMessage = ARGUMENTS + ".list[0]";
String firstAttachment = firstMessage + ".attachments[0]";
given()
@@ -2634,7 +3027,7 @@ public abstract class SetMessagesMethodTest {
.body(NAME, equalTo("messageList"))
.body(ARGUMENTS + ".messageIds", hasSize(1));
return true;
-
+
} catch (AssertionError e) {
return false;
}
@@ -2685,7 +3078,7 @@ public abstract class SetMessagesMethodTest {
calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken));
String inboxId = getMailboxId(accessToken, Role.INBOX);
- String receivedMessageId =
+ String receivedMessageId =
with()
.header("Authorization", accessToken.serialize())
.body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + inboxId + "\"]}}, \"#0\"]]")
@@ -2693,7 +3086,7 @@ public abstract class SetMessagesMethodTest {
.then()
.extract()
.path(ARGUMENTS + ".messageIds[0]");
-
+
String firstMessage = ARGUMENTS + ".list[0]";
String firstAttachment = firstMessage + ".attachments[0]";
given()
@@ -2758,7 +3151,7 @@ public abstract class SetMessagesMethodTest {
calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken));
String inboxId = getMailboxId(accessToken, Role.INBOX);
- String receivedMessageId =
+ String receivedMessageId =
with()
.header("Authorization", accessToken.serialize())
.body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + inboxId + "\"]}}, \"#0\"]]")
@@ -2766,7 +3159,7 @@ public abstract class SetMessagesMethodTest {
.then()
.extract()
.path(ARGUMENTS + ".messageIds[0]");
-
+
String firstMessage = ARGUMENTS + ".list[0]";
String firstAttachment = firstMessage + ".attachments[0]";
given()
@@ -2827,7 +3220,7 @@ public abstract class SetMessagesMethodTest {
calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken));
String inboxId = getMailboxId(accessToken, Role.INBOX);
- String receivedMessageId =
+ String receivedMessageId =
with()
.header("Authorization", accessToken.serialize())
.body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + inboxId + "\"]}}, \"#0\"]]")
@@ -2835,7 +3228,7 @@ public abstract class SetMessagesMethodTest {
.then()
.extract()
.path(ARGUMENTS + ".messageIds[0]");
-
+
String firstMessage = ARGUMENTS + ".list[0]";
String firstAttachment = firstMessage + ".attachments[0]";
given()
@@ -2856,7 +3249,7 @@ public abstract class SetMessagesMethodTest {
.body(firstAttachment + ".size", equalTo((int) attachment.getSize()));
}
@Test
- public void setMessageShouldVerifyHeaderOfMessageInInbox() throws Exception {
+ public void setMessagesShouldVerifyHeaderOfMessageInInbox() throws Exception {
String toUsername = "username1@" + USERS_DOMAIN;
String password = "password";
dataProbe.addUser(toUsername, password);
@@ -2893,7 +3286,7 @@ public abstract class SetMessagesMethodTest {
}
@Test
- public void setMessageShouldVerifyHeaderOfMessageInSent() throws Exception {
+ public void setMessagesShouldVerifyHeaderOfMessageInSent() throws Exception {
String toUsername = "username1@" + USERS_DOMAIN;
String password = "password";
dataProbe.addUser(toUsername, password);
@@ -2958,8 +3351,7 @@ public abstract class SetMessagesMethodTest {
.statusCode(200)
.body(ARGUMENTS + ".messageIds", hasSize(1))
.body(SECOND_NAME, equalTo("messages"))
- .body(SECOND_ARGUMENTS + ".list[0]", hasEntry(equalTo("headers"), allHeadersMatcher(expectedHeaders)))
- ;
+ .body(SECOND_ARGUMENTS + ".list[0]", hasEntry(equalTo("headers"), allHeadersMatcher(expectedHeaders)));
return true;
} catch(AssertionError e) {
e.printStackTrace();
@@ -3210,4 +3602,91 @@ public abstract class SetMessagesMethodTest {
.body(secondAttachment + ".cid", nullValue())
.body(secondAttachment + ".isInline", equalTo(true));
}
+
+ @Test
+ public void setMessageWithUpdateShouldBeOKWhenKeywordsWithCustomFlagArePassed() throws MailboxException {
+ mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
+
+ ComposedMessageId message = mailboxProbe.appendMessage(USERNAME, USER_MAILBOX,
+ new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes(Charsets.UTF_8)), new Date(), false, new Flags());
+ await();
+
+ String messageId = message.getMessageId().serialize();
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"keywords\": {\"$Seen\": true, \"$Unknown\": true} } } }, \"#0\"]]", messageId))
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .spec(getSetMessagesUpdateOKResponseAssertions(messageId));
+ }
+
+ @Test
+ public void setMessageWithCreationShouldBeOKWhenKeywordsWithCustomFlagArePassed() {
+ String messageCreationId = "creationId1337";
+ String fromAddress = USERNAME;
+ String requestBody = "[" +
+ " [" +
+ " \"setMessages\","+
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}," +
+ " \"to\": [{ \"name\": \"BOB\", \"email\": \"someone@example.com\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"keywords\": {\"$Draft\": true, \"$Unknown\": true}," +
+ " \"mailboxIds\": [\"" + getOutboxId(accessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(requestBody)
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("messagesSet"))
+ .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
+ .body(ARGUMENTS + ".created", aMapWithSize(1));
+ }
+
+ @Test
+ public void setMessageWithCreationShouldThrowWhenKeywordsWithUnsupportedArePassed() {
+ String messageCreationId = "creationId1337";
+ String fromAddress = USERNAME;
+ String requestBody = "[" +
+ " [" +
+ " \"setMessages\","+
+ " {" +
+ " \"create\": { \"" + messageCreationId + "\" : {" +
+ " \"from\": { \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}," +
+ " \"to\": [{ \"name\": \"BOB\", \"email\": \"someone@example.com\"}]," +
+ " \"subject\": \"subject\"," +
+ " \"keywords\": {\"$Draft\": true, \"$Deleted\": true}," +
+ " \"mailboxIds\": [\"" + getOutboxId(accessToken) + "\"]" +
+ " }}" +
+ " }," +
+ " \"#0\"" +
+ " ]" +
+ "]";
+
+ given()
+ .header("Authorization", accessToken.serialize())
+ .body(requestBody)
+ .when()
+ .post("/jmap")
+ .then()
+ .log().ifValidationFails()
+ .statusCode(200)
+ .body(NAME, equalTo("error"))
+ .body(ARGUMENTS + ".type", equalTo("invalidArguments"))
+ .body(ARGUMENTS + ".description", containsString("Does not allow to update 'Deleted' or 'Recent' flag"));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org