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