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 ad...@apache.org on 2017/12/01 15:37:10 UTC

[2/4] james-project git commit: JAMES-2244 Relax $Draft conditions

JAMES-2244 Relax $Draft conditions

    Still enforced restrictions:
      - Creation should be done with $Draft or in Outbox (Note that it was non explicitly enforced, as $Draft messages were necessarily in Drafts mailbox)
      - Only $Drafts messages can be sent (move)

    Relaxed conditions:
     - Now we can flip $Draft flag
     - Now we can move $Draft messages out of Drafts mailbox
     - Now we can have non $Draft messages in Drafts mailbox
     - Now I can create drafts 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/1eef6eab
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/1eef6eab
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/1eef6eab

Branch: refs/heads/master
Commit: 1eef6eabde66824e0e3d5dc9e1d2e3730e044fc1
Parents: d1ea4a2
Author: benwa <bt...@linagora.com>
Authored: Thu Nov 30 17:23:39 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Dec 1 13:51:43 2017 +0100

----------------------------------------------------------------------
 .../integration/SetMessagesMethodTest.java      | 26 +++-----
 .../cucumber/GetMessagesMethodStepdefs.java     |  2 +-
 .../cucumber/SetMessagesMethodStepdefs.java     | 10 ++-
 .../test/resources/cucumber/SetMessages.feature | 41 ++++++------
 .../exceptions/InvalidOutboxMoveException.java  |  3 +
 .../methods/SetMessagesCreationProcessor.java   | 18 ++----
 .../methods/SetMessagesUpdateProcessor.java     | 66 +++++---------------
 7 files changed, 64 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/1eef6eab/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 2470b51..5652090 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,7 +1356,7 @@ public abstract class SetMessagesMethodTest {
     }
 
     @Test
-    public void setMessagesShouldFailWhenSavingADraftInSeveralMailboxes() {
+    public void setMessagesShouldNotFailWhenSavingADraftInSeveralMailboxes() {
         String messageCreationId = "creationId1337";
         String fromAddress = USERNAME;
         MailboxId mailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, USERNAME, "mailbox");
@@ -1386,12 +1386,9 @@ public abstract class SetMessagesMethodTest {
             .log().ifValidationFails()
             .statusCode(200)
             .body(NAME, equalTo("messagesSet"))
-            .body(ARGUMENTS + ".created", aMapWithSize(0))
-            .body(ARGUMENTS + ".notCreated", aMapWithSize(1))
-            .body(ARGUMENTS + ".notCreated", hasKey(messageCreationId))
-            .body(ARGUMENTS + ".notCreated[\"" + messageCreationId + "\"].type", equalTo("invalidProperties"))
-            .body(ARGUMENTS + ".notCreated[\"" + messageCreationId + "\"].properties", contains("mailboxIds"))
-            .body(ARGUMENTS + ".notCreated[\"" + messageCreationId + "\"].description", equalTo("Message creation is only supported in mailboxes with role Draft and Outbox"));
+            .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
+            .body(ARGUMENTS + ".created", aMapWithSize(1))
+            .body(ARGUMENTS + ".created", hasKey(messageCreationId));
     }
 
     @Test
@@ -1499,12 +1496,9 @@ public abstract class SetMessagesMethodTest {
             .log().ifValidationFails()
             .statusCode(200)
             .body(NAME, equalTo("messagesSet"))
-            .body(ARGUMENTS + ".created", aMapWithSize(0))
-            .body(ARGUMENTS + ".notCreated", aMapWithSize(1))
-            .body(ARGUMENTS + ".notCreated", hasKey(messageCreationId))
-            .body(ARGUMENTS + ".notCreated[\"" + messageCreationId + "\"].type", equalTo("invalidProperties"))
-            .body(ARGUMENTS + ".notCreated[\"" + messageCreationId + "\"].properties", contains("mailboxIds"))
-            .body(ARGUMENTS + ".notCreated[\"" + messageCreationId + "\"].description", equalTo("Message creation is only supported in mailboxes with role Draft and Outbox"));
+            .body(ARGUMENTS + ".notCreated", aMapWithSize(0))
+            .body(ARGUMENTS + ".created", aMapWithSize(1))
+            .body(ARGUMENTS + ".created", hasKey(messageCreationId));
     }
 
     @Test
@@ -1985,8 +1979,8 @@ public abstract class SetMessagesMethodTest {
             .statusCode(200)
             .body(NAME, equalTo("messagesSet"))
             .body(ARGUMENTS + ".notUpdated", hasKey(draftId))
-            .body(ARGUMENTS + ".notUpdated[\""+draftId+"\"].type", equalTo("invalidArguments"))
-            .body(ARGUMENTS + ".notUpdated[\""+draftId+"\"].description", endsWith("One can not have a message in mailboxes that don't have all the `draft` role"))
+            .body(ARGUMENTS + ".notUpdated[\""+draftId+"\"].type", equalTo("invalidProperties"))
+            .body(ARGUMENTS + ".notUpdated[\""+draftId+"\"].description", endsWith("When moving a message to Outbox, only Outboxes mailboxes should be targeted."))
             .body(ARGUMENTS + ".notUpdated[\""+draftId+"\"].properties", hasSize(1))
             .body(ARGUMENTS + ".notUpdated[\""+draftId+"\"].properties", contains("mailboxIds"))
             .body(ARGUMENTS + ".created", aMapWithSize(0));
@@ -2021,7 +2015,7 @@ public abstract class SetMessagesMethodTest {
             .body(NAME, equalTo("messagesSet"))
             .body(ARGUMENTS + ".notUpdated", hasKey(messageId))
             .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].type", equalTo("invalidProperties"))
-            .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].description", endsWith("only drafts can be moved to Outbox"))
+            .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].description", endsWith("Only message with `$Draft` keyword can be moved to Outbox"))
             .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].properties", hasSize(1))
             .body(ARGUMENTS + ".notUpdated[\""+messageId+"\"].properties", contains("mailboxIds"))
             .body(ARGUMENTS + ".created", aMapWithSize(0));

http://git-wip-us.apache.org/repos/asf/james-project/blob/1eef6eab/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
index 2717d7e..0d86080 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/GetMessagesMethodStepdefs.java
@@ -697,7 +697,7 @@ public class GetMessagesMethodStepdefs {
             .isNullOrEmpty();
     }
 
-    @Then("^\"([^\"]*)\" should see message \"([^\"]*)\" with keywords (.*)$")
+    @Then("^\"([^\"]*)\" should see message \"([^\"]*)\" with keywords \"([^\"]*)\"$")
     public void assertKeywordsOfMessage(String user, String messageId, List<String> keywords) throws Exception {
         userStepdefs.execWithUser(user, () -> postWithAListOfIds(ImmutableList.of(messageId)));
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/1eef6eab/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMessagesMethodStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMessagesMethodStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMessagesMethodStepdefs.java
index 026ac90..e3e74a7 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMessagesMethodStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/SetMessagesMethodStepdefs.java
@@ -249,6 +249,8 @@ public class SetMessagesMethodStepdefs {
                 "    {" +
                 "      \"create\": { \"" + message  + "\" : {" +
                 "        \"subject\": \"subject\"," +
+                "        \"from\": { \"name\": \"Me\", \"email\": \"" + username + "\"}," +
+                "        \"to\": [{ \"name\": \"Me\", \"email\": \"" + username + "\"}]," +
                 "        \"keywords\": {\"$Draft\": true}," +
                 "        \"mailboxIds\": [\"" + mailbox.getMailboxId().serialize() + "\"]" +
                 "      }}" +
@@ -319,9 +321,15 @@ public class SetMessagesMethodStepdefs {
     }
 
     @Then("^message \"([^\"]*)\" is not created$")
-    public void assertNotCreated(String messageName) throws Exception {;
+    public void assertNotCreated(String messageName) throws Exception {
         assertThat(httpClient.jsonPath.<Map<String, String>>read("[0][1].notCreated"))
             .containsOnlyKeys(messageName);
     }
 
+    @Then("^message \"([^\"]*)\" is created$")
+    public void assertCreated(String messageName) throws Exception {
+        assertThat(httpClient.jsonPath.<Map<String, String>>read("[0][1].created"))
+            .containsOnlyKeys(messageName);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1eef6eab/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
index f3ac1bf..b3447fb 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/SetMessages.feature
@@ -55,7 +55,7 @@ Feature: SetMessages method on shared folders
     Given "bob@domain.tld" shares his mailbox "shared" with "alice@domain.tld" with "lriws" rights
     And "alice@domain.tld" sets flags "$Flagged" on message "mAlice"
     And "alice@domain.tld" moves "mAlice" to mailbox "shared" of user "bob@domain.tld"
-    Then "alice@domain.tld" should see message "mAlice" with keywords $Flagged
+    Then "alice@domain.tld" should see message "mAlice" with keywords "$Flagged"
 
   Scenario: A delegated user can add sanitized messages to a shared mailbox when missing "write" right
     Given "bob@domain.tld" shares his mailbox "shared" with "alice@domain.tld" with "lri" rights
@@ -83,12 +83,12 @@ Feature: SetMessages method on shared folders
   Scenario: A user can update the flags on a message
     Given "alice@domain.tld" sets flags "$Flagged,$Seen" on message "mAlice"
     When "alice@domain.tld" sets flags "$Flagged,$Forwarded" on message "mAlice"
-    Then "alice@domain.tld" should see message "mAlice" with keywords $Flagged,$Forwarded
+    Then "alice@domain.tld" should see message "mAlice" with keywords "$Flagged,$Forwarded"
 
   Scenario: A delegated user add keywords on a delegated message when having "write" right
     Given "bob@domain.tld" shares his mailbox "shared" with "alice@domain.tld" with "lrw" rights
     When "alice@domain.tld" sets flags "$Flagged" on message "mBob"
-    Then "alice@domain.tld" should see message "mBob" with keywords $Flagged
+    Then "alice@domain.tld" should see message "mBob" with keywords "$Flagged"
 
   Scenario: A delegated user can not add keywords on a delegated message when missing "write" right
     Given "bob@domain.tld" shares his mailbox "shared" with "alice@domain.tld" with "latires" rights
@@ -113,20 +113,20 @@ Feature: SetMessages method on shared folders
     Given "bob@domain.tld" has a mailbox "Drafts"
     And "bob@domain.tld" tries to create a draft message "mDraft" in mailbox "Drafts"
     When "bob@domain.tld" sets flags "$Draft,$Seen" on message "mDraft"
-    Then "bob@domain.tld" should see message "mDraft" with keywords $Draft,$Seen
+    Then "bob@domain.tld" should see message "mDraft" with keywords "$Draft,$Seen"
 
-  Scenario: A user can not remove a draft flag on a draft messages
+  Scenario: A user can remove a draft flag on a draft messages
     Given "bob@domain.tld" has a mailbox "Drafts"
     And "bob@domain.tld" tries to create a draft message "mDraft" in mailbox "Drafts"
     When "bob@domain.tld" sets flags "$Seen" on message "mDraft"
-    Then message "mDraft" is not updated
-    And "bob@domain.tld" should see message "mDraft" with keywords $Draft
+    Then message "mDraft" is updated
+    And "bob@domain.tld" should see message "mDraft" with keywords "$Seen"
 
   Scenario: A user can add a flag on a draft
     Given "bob@domain.tld" has a mailbox "Drafts"
     And "bob@domain.tld" tries to create a draft message "mDraft" in mailbox "Drafts"
     When "bob@domain.tld" marks the message "mDraft" as flagged
-    Then "bob@domain.tld" should see message "mDraft" with keywords $Draft,$Flagged
+    Then "bob@domain.tld" should see message "mDraft" with keywords "$Draft,$Flagged"
 
   Scenario: A user can destroy a draft
     Given "bob@domain.tld" has a mailbox "Drafts"
@@ -135,16 +135,21 @@ Feature: SetMessages method on shared folders
     Then "bob@domain.tld" ask for message "mDraft"
     And the notFound list should contain "mDraft"
 
-  Scenario: Draft creation in outbox is not allowed
+  Scenario: Draft creation in outbox is allowed
     Given "bob@domain.tld" has a mailbox "Outbox"
     When "bob@domain.tld" tries to create a draft message "mDraft" in mailbox "Outbox"
-    Then message "mDraft" is not created
+    Then message "mDraft" is created
 
-  Scenario: A user can not move draft out of draft mailbox
+  Scenario: Draft creation in any mailbox is allowed
+    Given "bob@domain.tld" has a mailbox "Outbox"
+    When "bob@domain.tld" tries to create a draft message "mDraft" in mailbox "shared"
+    Then message "mDraft" is created
+
+  Scenario: A user can move draft out of draft mailbox
     Given "bob@domain.tld" has a mailbox "Drafts"
     And "bob@domain.tld" tries to create a draft message "mDraft" in mailbox "Drafts"
     When "bob@domain.tld" moves "mDraft" to user mailbox "shared"
-    Then message "mDraft" is not updated
+    Then message "mDraft" is updated
 
   Scenario: A user can move draft out of draft mailbox when removing draft flag
     Given "bob@domain.tld" has a mailbox "Drafts"
@@ -164,18 +169,18 @@ Feature: SetMessages method on shared folders
     When the user moves "mBob" to user mailbox "Drafts" and set flags "$Draft"
     Then message "mBob" is updated
 
-  Scenario: A user can not copy draft out of draft mailbox
+  Scenario: A user can copy draft out of draft mailbox
     Given "bob@domain.tld" has a mailbox "Drafts"
     And "bob@domain.tld" tries to create a draft message "mDraft" in mailbox "Drafts"
     When "bob@domain.tld" copies "mDraft" from mailbox "Drafts" to mailbox "shared"
-    Then message "mDraft" is not updated
+    Then message "mDraft" is updated
 
-  Scenario: A user can not copy draft out of draft mailbox
+  Scenario: A user can copy draft out of draft mailbox
     Given "bob@domain.tld" has a mailbox "Drafts"
     When "bob@domain.tld" moves "mBob" to user mailbox "Drafts"
-    Then message "mBob" is not updated
+    Then message "mBob" is updated
 
-  Scenario: A user can not copy draft out of draft mailbox
+  Scenario: A user can copy draft out of draft mailbox
     Given "bob@domain.tld" has a mailbox "Drafts"
     When "bob@domain.tld" copies "mBob" from mailbox "shared" to mailbox "Drafts"
-    Then message "mBob" is not updated
\ No newline at end of file
+    Then message "mBob" is updated
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/1eef6eab/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/InvalidOutboxMoveException.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/InvalidOutboxMoveException.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/InvalidOutboxMoveException.java
index a70a750..dcf4b14 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/InvalidOutboxMoveException.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/exceptions/InvalidOutboxMoveException.java
@@ -20,4 +20,7 @@
 package org.apache.james.jmap.exceptions;
 
 public class InvalidOutboxMoveException extends RuntimeException {
+    public InvalidOutboxMoveException(String message) {
+        super(message);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1eef6eab/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 2f60b82..5cd4882 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
@@ -178,40 +178,30 @@ public class SetMessagesCreationProcessor implements SetMessagesProcessor {
     }
     
     private void performCreate(CreationMessageEntry entry, Builder responseBuilder, MailboxSession session) throws MailboxException, InvalidMailboxForCreationException, MessagingException, AttachmentsNotFoundException {
-        if (isAppendToMailboxWithRole(Role.DRAFTS, entry.getValue(), session)) {
+        if (isDraft(entry.getValue())) {
             saveDraft(entry, responseBuilder, session);
         } else if (isAppendToMailboxWithRole(Role.OUTBOX, entry.getValue(), session)) {
             sendMailViaOutbox(entry, responseBuilder, session);
         } else {
+            if (isAppendToMailboxWithRole(Role.DRAFTS, entry.getValue(), session)) {
+                throw new InvalidDraftKeywordsException("A draft message should be flagged as Draft");
+            }
             throw new InvalidMailboxForCreationException("The only implemented feature is sending via outbox and draft saving");
         }
     }
 
     private void sendMailViaOutbox(CreationMessageEntry entry, Builder responseBuilder, MailboxSession session) throws AttachmentsNotFoundException, MailboxException, MessagingException {
         validateArguments(entry, session);
-        assertNoDraftKeywords(entry.getValue());
         MessageWithId created = handleOutboxMessages(entry, session);
         responseBuilder.created(created.getCreationId(), created.getValue());
     }
 
     private void saveDraft(CreationMessageEntry entry, Builder responseBuilder, MailboxSession session) throws AttachmentsNotFoundException, MailboxException, MessagingException {
         attachmentChecker.assertAttachmentsExist(entry, session);
-        assertDraftKeywords(entry.getValue());
         MessageWithId created = handleDraftMessages(entry, session);
         responseBuilder.created(created.getCreationId(), created.getValue());
     }
 
-    private void assertDraftKeywords(CreationMessage creationMessage) {
-        if (!isDraft(creationMessage)) {
-            throw new InvalidDraftKeywordsException("A draft message should be flagged as Draft");
-        }
-    }
-
-    private void assertNoDraftKeywords(CreationMessage creationMessage) {
-        if (isDraft(creationMessage)) {
-            throw new InvalidDraftKeywordsException("A draft message can not be created out of draft mailbox");
-        }
-    }
 
     private Boolean isDraft(CreationMessage creationMessage) {
         if (creationMessage.getOldKeyword().isPresent()) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/1eef6eab/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
index 9086ea6..3fd703b 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesUpdateProcessor.java
@@ -139,7 +139,7 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
         } catch (InvalidOutboxMoveException e) {
             ValidationResult invalidPropertyMailboxIds = ValidationResult.builder()
                 .property(MessageProperties.MessageProperty.mailboxIds.asFieldName())
-                .message("only drafts can be moved to Outbox")
+                .message(e.getMessage())
                 .build();
 
             handleInvalidRequest(builder, messageId, ImmutableList.of(invalidPropertyMailboxIds));
@@ -180,58 +180,33 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
     }
 
     private void assertValidUpdate(List<MessageResult> messagesToBeUpdated, UpdateMessagePatch updateMessagePatch, MailboxSession session) throws MailboxException {
-        List<MailboxId> draftMailboxes = mailboxIdFor(Role.DRAFTS, session);
         List<MailboxId> outboxMailboxes = mailboxIdFor(Role.OUTBOX, session);
 
         ImmutableList<MailboxId> previousMailboxes = messagesToBeUpdated.stream()
             .map(MessageResult::getMailboxId)
             .collect(Guavate.toImmutableList());
-        List<Flags> futureFlags = patchFlags(messagesToBeUpdated, updateMessagePatch);
         List<MailboxId> targetMailboxes = getTargetedMailboxes(previousMailboxes, updateMessagePatch);
 
-        boolean originIsDraft = previousMailboxes.stream().allMatch(draftMailboxes::contains);
-        boolean targetIsOutbox = targetMailboxes.stream().anyMatch(outboxMailboxes::contains);
-        boolean targetHasDraft = targetMailboxes.stream().anyMatch(draftMailboxes::contains);
-        boolean targetHasNonDraft = targetMailboxes.stream().anyMatch(id -> !draftMailboxes.contains(id));
+        boolean allMessagesWereDrafts = messagesToBeUpdated.stream()
+            .map(MessageResult::getFlags)
+            .allMatch(flags -> flags.contains(Flags.Flag.DRAFT));
 
-        assertValidUpdate(futureFlags, targetHasDraft, targetHasNonDraft, targetIsOutbox, originIsDraft);
-    }
+        boolean targetContainsOutbox = targetMailboxes.stream().anyMatch(outboxMailboxes::contains);
+        boolean targetIsOnlyOutbox = targetMailboxes.stream().allMatch(outboxMailboxes::contains);
 
-    private void assertValidUpdate(List<Flags> futureFlags, boolean targetHasDraft, boolean targetHasNonDraft,
-                                   boolean targetIsOutbox, boolean originIsDraft) throws DraftMessageMailboxUpdateException {
-        assertMessageIsNotInDraftAndNonDraftMailboxes(targetHasDraft, targetHasNonDraft);
-        assertNoNonDraftMessageInsideDraftMailbox(futureFlags, targetHasDraft);
-        assertNoDraftMessageOutOfDraftMailbox(futureFlags, targetHasNonDraft);
-        assertOutboxMoveOnlyFromDraft(targetIsOutbox, originIsDraft);
+        assertOutboxMoveTargetsOnlyOutBox(targetContainsOutbox, targetIsOnlyOutbox);
+        assertOutboxMoveOriginallyHasDraftKeywordSet(targetContainsOutbox, allMessagesWereDrafts);
     }
 
-    private void assertOutboxMoveOnlyFromDraft(boolean targetIsOutbox, boolean originIsDraft) {
-        if (targetIsOutbox && !originIsDraft) {
-            throw new InvalidOutboxMoveException();
+    private void assertOutboxMoveTargetsOnlyOutBox(boolean targetContainsOutbox, boolean targetIsOnlyOutbox) {
+        if (targetContainsOutbox && !targetIsOnlyOutbox) {
+            throw new InvalidOutboxMoveException("When moving a message to Outbox, only Outboxes mailboxes should be targeted.");
         }
     }
 
-    private void assertMessageIsNotInDraftAndNonDraftMailboxes(boolean targetHasDraft, boolean targetHasNonDraft) throws DraftMessageMailboxUpdateException {
-        if (targetHasDraft && targetHasNonDraft) {
-            throw new DraftMessageMailboxUpdateException("One can not have a message in mailboxes that don't have all the `draft` role");
-        }
-    }
-
-    private void assertNoNonDraftMessageInsideDraftMailbox(List<Flags> futureFlags, boolean targetHasDraft) throws DraftMessageMailboxUpdateException {
-        if (targetHasDraft) {
-            boolean anyNonDraftMessage = futureFlags.stream().anyMatch(flags -> !flags.contains(Flags.Flag.DRAFT));
-            if (anyNonDraftMessage) {
-                throw new DraftMessageMailboxUpdateException("Messages without '$Draft' keyword are prohibited in drafts mailboxes");
-            }
-        }
-    }
-
-    private void assertNoDraftMessageOutOfDraftMailbox(List<Flags> futureFlags, boolean targetHasNonDraft) throws DraftMessageMailboxUpdateException {
-        if (targetHasNonDraft) {
-            boolean anyDraftMessage = futureFlags.stream().anyMatch(flags -> flags.contains(Flags.Flag.DRAFT));
-            if (anyDraftMessage) {
-                throw new DraftMessageMailboxUpdateException("Messages with '$Draft' keyword are prohibited in non drafts mailboxes");
-            }
+    private void assertOutboxMoveOriginallyHasDraftKeywordSet(boolean targetIsOutbox, boolean allMessagesWereDrafts) {
+        if (targetIsOutbox && !allMessagesWereDrafts) {
+            throw new InvalidOutboxMoveException("Only message with `$Draft` keyword can be moved to Outbox");
         }
     }
 
@@ -241,12 +216,6 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
             .orElse(previousMailboxes);
     }
 
-    private List<Flags> patchFlags(List<MessageResult> messagesToBeUpdated, UpdateMessagePatch updateMessagePatch) {
-        return updateMessagePatch.getOldKeyword()
-                .map(oldKeyword -> flagsFromOldKeyword(messagesToBeUpdated, oldKeyword))
-                .orElse(flagsFromKeywords(messagesToBeUpdated, updateMessagePatch));
-    }
-
     private List<Flags> flagsFromOldKeyword(List<MessageResult> messagesToBeUpdated, OldKeyword oldKeyword) {
         return messagesToBeUpdated.stream()
                 .map(MessageResult::getFlags)
@@ -254,13 +223,6 @@ public class SetMessagesUpdateProcessor implements SetMessagesProcessor {
                 .collect(Guavate.toImmutableList());
     }
 
-    private ImmutableList<Flags> flagsFromKeywords(List<MessageResult> messagesToBeUpdated, UpdateMessagePatch updateMessagePatch) {
-        return messagesToBeUpdated.stream()
-                .map(MessageResult::getFlags)
-                .map(updateMessagePatch::applyToState)
-                .collect(Guavate.toImmutableList());
-    }
-
     private List<MailboxId> mailboxIdFor(Role role, MailboxSession session) throws MailboxException {
         return systemMailboxesProvider.getMailboxByRole(role, session)
             .map(MessageManager::getId)


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