JAMES-2244 Allow draft creation out of Draft mailbox

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

Branch: refs/heads/master
Commit: 38acce2302a3851de89dfde618a8774c86aadf5c
Parents: 66f19b2
Author: benwa <btell...@linagora.com>
Authored: Tue Dec 12 16:06:21 2017 +0700
Committer: benwa <btell...@linagora.com>
Committed: Thu Dec 14 16:03:46 2017 +0700

----------------------------------------------------------------------
 .../integration/SetMessagesMethodTest.java      | 78 ++++++++++++++++++++
 .../james/jmap/methods/MessageAppender.java     | 16 +++-
 .../methods/SetMessagesCreationProcessor.java   | 11 ++-
 .../SetMessagesCreationProcessorTest.java       |  3 +
 4 files changed, 98 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/38acce23/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 3a6893f..196fb6a 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
@@ -1356,6 +1356,84 @@ public abstract class SetMessagesMethodTest {
     }
 
     @Test
+    public void setMessagesShouldCreateDraftInSeveralMailboxes() {
+        MailboxId mailboxId = 
mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, 
"mailbox");
+        String messageCreationId = "creationId1337";
+        String fromAddress = USERNAME;
+        String draftId = getDraftId(accessToken);
+        String requestBody = "[" +
+            "  [" +
+            "    \"setMessages\","+
+            "    {" +
+            "      \"create\": { \"" + messageCreationId  + "\" : {" +
+            "        \"from\": { \"name\": \"Me\", \"email\": \"" + 
fromAddress + "\"}," +
+            "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+            "        \"subject\": \"subject\"," +
+            "        \"keywords\": {\"$Draft\": true}," +
+            "        \"mailboxIds\": [\"" + mailboxId.serialize() + "\", \"" + 
draftId + "\"]" +
+            "      }}" +
+            "    }," +
+            "    \"#0\"" +
+            "  ]" +
+            "]";
+
+        String messageId = given()
+            .header("Authorization", accessToken.serialize())
+            .body(requestBody)
+        .when()
+            .post("/jmap")
+        .then()
+            .extract()
+            .body()
+            .path(ARGUMENTS + ".created." + messageCreationId + ".id");
+
+        with()
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + messageId + "\"]}, 
\"#0\"]]")
+            .post("/jmap")
+        .then()
+            .log().ifValidationFails()
+            .body(NAME, equalTo("messages"))
+            .body(ARGUMENTS + ".list", hasSize(1))
+            .body(ARGUMENTS + ".list[0].mailboxIds", 
containsInAnyOrder(mailboxId.serialize(), draftId));
+    }
+
+    @Test
+    public void setMessagesShouldAllowDraftCreationOutsideOfDraftMailbox() {
+        MailboxId mailboxId = 
mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, 
"mailbox");
+        String messageCreationId = "creationId1337";
+        String fromAddress = USERNAME;
+        String requestBody = "[" +
+            "  [" +
+            "    \"setMessages\","+
+            "    {" +
+            "      \"create\": { \"" + messageCreationId  + "\" : {" +
+            "        \"from\": { \"name\": \"Me\", \"email\": \"" + 
fromAddress + "\"}," +
+            "        \"to\": [{ \"name\": \"BOB\", \"email\": 
\"some...@example.com\"}]," +
+            "        \"subject\": \"subject\"," +
+            "        \"keywords\": {\"$Draft\": true}," +
+            "        \"mailboxIds\": [\"" + mailboxId.serialize() + "\"]" +
+            "      }}" +
+            "    }," +
+            "    \"#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));
+    }
+
+    @Test
     public void setMessagesShouldRejectMessageCreationWithNoMailbox() {
         String messageCreationId = "creationId1337";
         String fromAddress = USERNAME;

http://git-wip-us.apache.org/repos/asf/james-project/blob/38acce23/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MessageAppender.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MessageAppender.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MessageAppender.java
index 5ca9ab3..7bb2edc 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MessageAppender.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MessageAppender.java
@@ -52,6 +52,7 @@ import org.slf4j.LoggerFactory;
 import com.github.fge.lambdas.Throwing;
 import com.github.fge.lambdas.functions.ThrowingFunction;
 import com.github.steveash.guavate.Guavate;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 public class MessageAppender {
@@ -70,9 +71,10 @@ public class MessageAppender {
         this.mimeMessageConverter = mimeMessageConverter;
     }
 
-    public MessageFactory.MetaDataWithContent 
appendMessageInMailbox(CreationMessageEntry createdEntry,
-                                                                     
List<MailboxId> targetMailboxes,
-                                                                     
MailboxSession session) throws MailboxException {
+    public MessageFactory.MetaDataWithContent 
appendMessageInMailboxes(CreationMessageEntry createdEntry,
+                                                                       
List<MailboxId> targetMailboxes,
+                                                                       
MailboxSession session) throws MailboxException {
+        Preconditions.checkArgument(!targetMailboxes.isEmpty());
         ImmutableList<MessageAttachment> messageAttachments = 
getMessageAttachments(session, createdEntry.getValue().getAttachments());
         byte[] messageContent = mimeMessageConverter.convert(createdEntry, 
messageAttachments);
         SharedByteArrayInputStream content = new 
SharedByteArrayInputStream(messageContent);
@@ -81,7 +83,7 @@ public class MessageAppender {
         boolean notRecent = false;
         MessageManager mailbox = 
mailboxManager.getMailbox(targetMailboxes.get(0), session);
         ComposedMessageId message = mailbox.appendMessage(content, 
internalDate, session, notRecent, getFlags(createdEntry.getValue()));
-        if (targetMailboxes.size() > 0) {
+        if (targetMailboxes.size() > 1) {
             messageIdManager.setInMailboxes(message.getMessageId(), 
targetMailboxes, session);
         }
 
@@ -97,6 +99,12 @@ public class MessageAppender {
             .build();
     }
 
+    public MessageFactory.MetaDataWithContent 
appendMessageInMailbox(CreationMessageEntry createdEntry,
+                                                                       
MailboxId targetMailbox,
+                                                                       
MailboxSession session) throws MailboxException {
+        return appendMessageInMailboxes(createdEntry, 
ImmutableList.of(targetMailbox), session);
+    }
+
     private Flags getFlags(CreationMessage message) {
         return message.getOldKeyword()
                 .map(OldKeyword::asFlags)

http://git-wip-us.apache.org/repos/asf/james-project/blob/38acce23/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
index b8f820b..00e4c1c 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
@@ -258,22 +258,22 @@ public class SetMessagesCreationProcessor implements 
SetMessagesProcessor {
     }
 
     @VisibleForTesting void assertIsUserOwnerOfMailboxes(List<MailboxId> 
mailboxIds, MailboxSession session) throws MailboxNotOwnedException {
-        if (containsMailboxNotOwn(mailboxIds, session)) {
+        if (!allMailboxOwned(mailboxIds, session)) {
             throw new MailboxNotOwnedException();
         }
     }
 
-    private boolean containsMailboxNotOwn(List<MailboxId> mailboxIds, 
MailboxSession session) {
+    private boolean allMailboxOwned(List<MailboxId> mailboxIds, MailboxSession 
session) {
         FunctionChainer<MailboxId, MessageManager> findMailbox = 
Throwing.function(mailboxId -> mailboxManager.getMailbox(mailboxId, session));
         return mailboxIds.stream()
             .map(findMailbox.sneakyThrow())
             .map(Throwing.function(MessageManager::getMailboxPath))
-            .anyMatch(path -> !path.belongsTo(session));
+            .allMatch(path -> path.belongsTo(session));
     }
 
     private MessageWithId handleOutboxMessages(CreationMessageEntry entry, 
MailboxSession session) throws MailboxException, MessagingException {
         assertUserIsSender(session, entry.getValue().getFrom());
-        MetaDataWithContent newMessage = 
messageAppender.appendMessageInMailbox(entry, toMailboxIds(entry), session);
+        MetaDataWithContent newMessage = 
messageAppender.appendMessageInMailboxes(entry, toMailboxIds(entry), session);
         Message jmapMessage = 
messageFactory.fromMetaDataWithContent(newMessage);
         Envelope envelope = Envelope.fromMessage(jmapMessage);
         messageSender.sendMessage(newMessage, envelope, session);
@@ -290,8 +290,7 @@ public class SetMessagesCreationProcessor implements 
SetMessagesProcessor {
     }
 
     private MessageWithId handleDraftMessages(CreationMessageEntry entry, 
MailboxSession session) throws MailboxException, MessagingException {
-        MessageManager draftMailbox = getMailboxWithRole(session, 
Role.DRAFTS).orElseThrow(() -> new 
MailboxNotFoundException(Role.DRAFTS.serialize()));
-        MetaDataWithContent newMessage = 
messageAppender.appendMessageInMailbox(entry, 
ImmutableList.of(draftMailbox.getId()), session);
+        MetaDataWithContent newMessage = 
messageAppender.appendMessageInMailboxes(entry, toMailboxIds(entry), session);
         Message jmapMessage = 
messageFactory.fromMetaDataWithContent(newMessage);
         return new ValueWithId.MessageWithId(entry.getCreationId(), 
jmapMessage);
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/38acce23/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
index ebdcc83..022be44 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetMessagesCreationProcessorTest.java
@@ -22,6 +22,7 @@ package org.apache.james.jmap.methods;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -289,6 +290,7 @@ public class SetMessagesCreationProcessorTest {
                     .build();
         when(mockedMailboxManager.getMailbox(any(MailboxId.class), any()))
             .thenReturn(outbox);
+        
when(mockedMailboxIdFactory.fromString(anyString())).thenReturn(OUTBOX_ID);
 
         sut.process(notInOutboxCreationRequest, session);
 
@@ -306,6 +308,7 @@ public class SetMessagesCreationProcessorTest {
                 .build();
         when(mockedMailboxManager.getMailbox(any(MailboxId.class), any()))
             .thenReturn(drafts);
+        
when(mockedMailboxIdFactory.fromString(anyString())).thenReturn(DRAFTS_ID);
         
         sut.process(createMessageInDrafts, session);
 


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

Reply via email to