JAMES-2257 Allow Message::isDraft property modification via JMAP

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

Branch: refs/heads/master
Commit: e9ef473946a5f8a13100e18d65d19183adde4124
Parents: 9d2f656
Author: benwa <btell...@linagora.com>
Authored: Mon Dec 11 17:19:32 2017 +0700
Committer: benwa <btell...@linagora.com>
Committed: Fri Dec 15 14:00:36 2017 +0700

----------------------------------------------------------------------
 .../integration/SetMessagesMethodTest.java      |  2 --
 .../cucumber/SetMessagesMethodStepdefs.java     | 21 ++++++++++++
 .../test/resources/cucumber/SetMessages.feature |  5 +++
 .../james/jmap/model/CreationMessage.java       |  9 ++----
 .../org/apache/james/jmap/model/OldKeyword.java | 10 +++++-
 .../james/jmap/model/UpdateMessagePatch.java    | 17 +++++-----
 .../apache/james/jmap/model/OldKeywordTest.java | 34 +++++++++++++-------
 7 files changed, 68 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/e9ef4739/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 2083038..4b40022 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
@@ -5192,7 +5192,6 @@ public abstract class SetMessagesMethodTest {
             .body(ARGUMENTS + ".list[0].isForwarded", equalTo(true));
     }
 
-    @Ignore("JAMES-2257 isDraft is rejected during message creation")
     @Test
     public void 
setMessagesShouldNotReturnAnErrorWhenTryingToChangeDraftFlagAmongOthers() {
         String messageCreationId = "creationId1337";
@@ -5255,7 +5254,6 @@ public abstract class SetMessagesMethodTest {
 
     }
 
-    @Ignore("JAMES-2257 isDraft is rejected during message creation")
     @Test
     public void 
setMessagesShouldModifyTheMessageWhenTryingToChangeDraftFlagAmongOthers() {
         String messageCreationId = "creationId1337";

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9ef4739/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 ffa9981..be925cb 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
@@ -199,6 +199,27 @@ public class SetMessagesMethodStepdefs {
         });
     }
 
+    @When("^\"([^\"]*)\" marks the message \"([^\"]*)\" as draft")
+    public void draft(String username, String message) throws Throwable {
+        userStepdefs.execWithUser(username, () -> {
+            MessageId messageId = messageIdStepdefs.getMessageId(message);
+
+            httpClient.post("[" +
+                "  [" +
+                "    \"setMessages\"," +
+                "    {" +
+                "      \"update\": { \"" + messageId.serialize() + "\" : {" +
+                "        \"isDraft\": true" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]");
+            mainStepdefs.awaitMethod.run();
+        });
+    }
+
+
     @When("^\"([^\"]*)\" destroys message \"([^\"]*)\"$")
     public void destroyMessage(String username, String message) {
         MessageId messageId = messageIdStepdefs.getMessageId(message);

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9ef4739/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 ffe6eec..36a1cf9 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
@@ -98,6 +98,11 @@ Feature: SetMessages method
     When "b...@domain.tld" moves "mBob" to user mailbox "Drafts"
     Then message "mBob" is updated
 
+  Scenario: A user can update $Draft keyword using isDraft property
+    Given "b...@domain.tld" has a mailbox "Drafts"
+    When "b...@domain.tld" marks the message "mBob" as draft
+    Then message "mBob" is updated
+
   Scenario: A user can copy draft out of draft mailbox
     Given "b...@domain.tld" has a mailbox "Drafts"
     When "b...@domain.tld" copies "mBob" from mailbox "mailbox" to mailbox 
"Drafts"

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9ef4739/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/CreationMessage.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/CreationMessage.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/CreationMessage.java
index 377fce9..625f42d 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/CreationMessage.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/CreationMessage.java
@@ -221,7 +221,8 @@ public class CreationMessage {
             }
 
             Optional<Keywords> maybeKeywords = creationKeywords();
-            Optional<OldKeyword> oldKeywords = getOldKeywords();
+            Optional<OldKeyword> oldKeywords = OldKeyword.computeOldKeywords(
+                isUnread, isFlagged, isAnswered, isDraft, isForwarded);
             Preconditions.checkArgument(!(maybeKeywords.isPresent() && 
oldKeywords.isPresent()), "Does not support keyword and is* at the same time");
             return new CreationMessage(mailboxIds, 
Optional.ofNullable(inReplyToMessageId), headers.build(), from,
                     to.build(), cc.build(), bcc.build(), replyTo.build(), 
subject, date, Optional.ofNullable(textBody), Optional.ofNullable(htmlBody),
@@ -234,12 +235,6 @@ public class CreationMessage {
                     .fromMap(map));
         }
 
-        private Optional<OldKeyword> getOldKeywords() {
-            if (isAnswered.isPresent() || isFlagged.isPresent() || 
isUnread.isPresent() || isDraft.isPresent() || isForwarded.isPresent()) {
-                return Optional.of(new OldKeyword(isUnread, isFlagged, 
isAnswered, isDraft, isForwarded));
-            }
-            return Optional.empty();
-        }
     }
 
     private final ImmutableList<String> mailboxIds;

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9ef4739/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/OldKeyword.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/OldKeyword.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/OldKeyword.java
index 7620873..b240b54 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/OldKeyword.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/OldKeyword.java
@@ -28,6 +28,14 @@ import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
 
 public class OldKeyword {
+    public static Optional<OldKeyword> computeOldKeywords(Optional<Boolean> 
isUnread, Optional<Boolean> isFlagged, Optional<Boolean> isAnswered,
+                                                          Optional<Boolean> 
isDraft, Optional<Boolean> isForwarded) {
+        if (isAnswered.isPresent() || isFlagged.isPresent() || 
isUnread.isPresent() || isForwarded.isPresent() || isDraft.isPresent()) {
+            return Optional.of(new OldKeyword(isUnread, isFlagged, isAnswered, 
isDraft, isForwarded));
+        }
+        return Optional.empty();
+    }
+
     private final Optional<Boolean> isUnread;
     private final Optional<Boolean> isFlagged;
     private final Optional<Boolean> isAnswered;
@@ -43,7 +51,7 @@ public class OldKeyword {
         this.isForwarded = Optional.of(isForwarded);
     }
 
-    public OldKeyword(Optional<Boolean> isUnread, Optional<Boolean> isFlagged, 
Optional<Boolean> isAnswered,
+    private OldKeyword(Optional<Boolean> isUnread, Optional<Boolean> 
isFlagged, Optional<Boolean> isAnswered,
                       Optional<Boolean> isDraft, Optional<Boolean> 
isForwarded) {
         this.isUnread = isUnread;
         this.isFlagged = isFlagged;

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9ef4739/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/UpdateMessagePatch.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/UpdateMessagePatch.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/UpdateMessagePatch.java
index e735778..19671a9 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/UpdateMessagePatch.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/UpdateMessagePatch.java
@@ -51,6 +51,7 @@ public class UpdateMessagePatch {
         private Optional<Boolean> isUnread = Optional.empty();
         private Optional<Boolean> isAnswered = Optional.empty();
         private Optional<Boolean> isForwarded = Optional.empty();
+        private Optional<Boolean> isDraft = Optional.empty();
         private Optional<Map<String, Boolean>> keywords = Optional.empty();
         private Set<ValidationResult> validationResult = Sets.newHashSet();
 
@@ -79,6 +80,11 @@ public class UpdateMessagePatch {
             return this;
         }
 
+        public Builder isDraft(Boolean isAnswered) {
+            this.isDraft = Optional.of(isAnswered);
+            return this;
+        }
+
         public Builder isForwarded(Boolean isForwarded) {
             this.isForwarded = Optional.of(isForwarded);
             return this;
@@ -98,7 +104,8 @@ public class UpdateMessagePatch {
             }
 
             Optional<Keywords> mayBeKeywords = creationKeywords();
-            Optional<OldKeyword> oldKeywords = getOldKeywords();
+            Optional<OldKeyword> oldKeywords = OldKeyword.computeOldKeywords(
+                isUnread, isFlagged, isAnswered, isDraft, isForwarded);
             Preconditions.checkArgument(!(mayBeKeywords.isPresent() && 
oldKeywords.isPresent()), "Does not support keyword and is* at the same time");
 
             return new UpdateMessagePatch(mailboxIds, mayBeKeywords, 
oldKeywords, ImmutableList.copyOf(validationResult));
@@ -110,14 +117,6 @@ public class UpdateMessagePatch {
                     .fromMap(map));
         }
 
-        private Optional<OldKeyword> getOldKeywords() {
-            if (isAnswered.isPresent() || isFlagged.isPresent() || 
isUnread.isPresent() || isForwarded.isPresent()) {
-                Optional<Boolean> isDraft = Optional.empty();
-                return Optional.of(new OldKeyword(isUnread, isFlagged, 
isAnswered, isDraft, isForwarded));
-            }
-            return Optional.empty();
-        }
-
     }
 
     private final Optional<List<String>> mailboxIds;

http://git-wip-us.apache.org/repos/asf/james-project/blob/e9ef4739/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/OldKeywordTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/OldKeywordTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/OldKeywordTest.java
index 46db6b8..3d28be6 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/OldKeywordTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/OldKeywordTest.java
@@ -37,15 +37,27 @@ public class OldKeywordTest {
     }
 
     @Test
+    public void computeOldKeywordsShouldReturnEmptyWhenAllEmpty() {
+        Optional<Boolean> isUnread = Optional.empty();
+        Optional<Boolean> isFlagged = Optional.empty();
+        Optional<Boolean> isAnswered = Optional.empty();
+        Optional<Boolean> isDraft = Optional.empty();
+        Optional<Boolean> isForwarded = Optional.empty();
+        Optional<OldKeyword> testee = OldKeyword.computeOldKeywords(isUnread, 
isFlagged, isAnswered, isDraft, isForwarded);
+
+        assertThat(testee).isEmpty();
+    }
+
+    @Test
     public void applyStateShouldSetFlaggedOnlyWhenIsFlagged() {
         Optional<Boolean> isUnread = Optional.empty();
         Optional<Boolean> isFlagged = Optional.of(true);
         Optional<Boolean> isAnswered = Optional.empty();
         Optional<Boolean> isDraft = Optional.empty();
         Optional<Boolean> isForwarded = Optional.empty();
-        OldKeyword testee = new OldKeyword(isUnread, isFlagged, isAnswered, 
isDraft, isForwarded);
-        
-        assertThat(testee.applyToState(new Flags())).isEqualTo(new 
Flags(Flag.FLAGGED));
+        Optional<OldKeyword> testee = OldKeyword.computeOldKeywords(isUnread, 
isFlagged, isAnswered, isDraft, isForwarded);
+
+        assertThat(testee.get().applyToState(new Flags())).isEqualTo(new 
Flags(Flag.FLAGGED));
     }
 
     @Test
@@ -55,9 +67,9 @@ public class OldKeywordTest {
         Optional<Boolean> isAnswered = Optional.empty();
         Optional<Boolean> isDraft = Optional.empty();
         Optional<Boolean> isForwarded = Optional.empty();
-        OldKeyword testee = new OldKeyword(isUnread, isFlagged, isAnswered, 
isDraft, isForwarded);
+        Optional<OldKeyword> testee = OldKeyword.computeOldKeywords(isUnread, 
isFlagged, isAnswered, isDraft, isForwarded);
         
-        assertThat(testee.applyToState(new Flags(Flag.FLAGGED))).isEqualTo(new 
Flags());
+        assertThat(testee.get().applyToState(new 
Flags(Flag.FLAGGED))).isEqualTo(new Flags());
     }
 
     @Test
@@ -67,9 +79,9 @@ public class OldKeywordTest {
         Optional<Boolean> isAnswered = Optional.empty();
         Optional<Boolean> isDraft = Optional.empty();
         Optional<Boolean> isForwarded = Optional.empty();
-        OldKeyword testee = new OldKeyword(isUnread, isFlagged, isAnswered, 
isDraft, isForwarded);
-        
-        assertThat(testee.applyToState(new Flags(Flag.SEEN))).isEqualTo(new 
Flags());
+        Optional<OldKeyword> testee = OldKeyword.computeOldKeywords(isUnread, 
isFlagged, isAnswered, isDraft, isForwarded);
+
+        assertThat(testee.get().applyToState(new 
Flags(Flag.SEEN))).isEqualTo(new Flags());
     }
 
     @Test
@@ -79,8 +91,8 @@ public class OldKeywordTest {
         Optional<Boolean> isAnswered = Optional.empty();
         Optional<Boolean> isDraft = Optional.empty();
         Optional<Boolean> isForwarded = Optional.empty();
-        OldKeyword testee = new OldKeyword(isUnread, isFlagged, isAnswered, 
isDraft, isForwarded);
-        
-        assertThat(testee.applyToState(new Flags(Flag.SEEN))).isEqualTo(new 
Flags(Flag.SEEN));
+        Optional<OldKeyword> testee = OldKeyword.computeOldKeywords(isUnread, 
isFlagged, isAnswered, isDraft, isForwarded);
+
+        assertThat(testee.get().applyToState(new 
Flags(Flag.SEEN))).isEqualTo(new Flags(Flag.SEEN));
     }
 }
\ No newline at end of file


---------------------------------------------------------------------
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