JAMES-2213 GetMessageList should support filtering by isForwarded

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

Branch: refs/heads/master
Commit: a345a328c83d838a2f0e7ba5d1d4fc091f5ef0c7
Parents: b1e43fc
Author: quynhn <qngu...@linagora.com>
Authored: Mon Nov 13 11:34:05 2017 +0700
Committer: quynhn <qngu...@linagora.com>
Committed: Tue Nov 14 10:27:40 2017 +0700

----------------------------------------------------------------------
 .../integration/GetMessageListMethodTest.java   | 50 +++++++++++++++++++-
 .../james/jmap/model/FilterCondition.java       | 22 +++++++--
 .../james/jmap/utils/FilterToSearchQuery.java   |  2 +
 .../james/jmap/model/FilterConditionTest.java   |  4 +-
 4 files changed, 73 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a345a328/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
index e9b1ea4..9423e41 100644
--- 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
@@ -396,7 +396,55 @@ public abstract class GetMessageListMethodTest {
                     
containsInAnyOrder(messageNotAnswered.getMessageId().serialize()), 
                     
not(containsInAnyOrder(messageAnswered.getMessageId().serialize()))));
     }
-    
+
+    @Test
+    public void 
getMessageListSetForwardedFilterShouldReturnOnlyForwardedMessages() throws 
Exception {
+        mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, alice, 
"mailbox");
+
+        ComposedMessageId messageNotForwarded = 
mailboxProbe.appendMessage(alice, MailboxPath.forUser(alice, "mailbox"),
+            new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        ComposedMessageId messageForwarded = mailboxProbe.appendMessage(alice, 
MailboxPath.forUser(alice, "mailbox"),
+            ClassLoader.getSystemResourceAsStream("eml/twoAttachments.eml"), 
new Date(), false, new Flags(FORWARDED));
+
+        await();
+
+        given()
+            .header("Authorization", aliceAccessToken.serialize())
+            .body("[[\"getMessageList\", 
{\"filter\":{\"isForwarded\":\"true\"}}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messageList"))
+            .body(ARGUMENTS + ".messageIds", allOf(
+                
containsInAnyOrder(messageForwarded.getMessageId().serialize()),
+                
not(containsInAnyOrder(messageNotForwarded.getMessageId().serialize()))));
+    }
+
+    @Test
+    public void 
getMessageListUnsetForwardedFilterShouldReturnOnlyNotForwardedMessages() throws 
Exception {
+        mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, alice, 
"mailbox");
+
+        ComposedMessageId messageNotForwarded = 
mailboxProbe.appendMessage(alice, MailboxPath.forUser(alice, "mailbox"),
+            new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        ComposedMessageId messageForwarded = mailboxProbe.appendMessage(alice, 
MailboxPath.forUser(alice, "mailbox"),
+            ClassLoader.getSystemResourceAsStream("eml/twoAttachments.eml"), 
new Date(), false, new Flags(FORWARDED));
+
+        await();
+
+        given()
+            .header("Authorization", aliceAccessToken.serialize())
+            .body("[[\"getMessageList\", 
{\"filter\":{\"isForwarded\":\"false\"}}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messageList"))
+            .body(ARGUMENTS + ".messageIds", allOf(
+                
containsInAnyOrder(messageNotForwarded.getMessageId().serialize()),
+                
not(containsInAnyOrder(messageForwarded.getMessageId().serialize()))));
+    }
+
     @Test
     public void 
getMessageListANDOperatorShouldReturnMessagesWhichMatchAllConditions() throws 
Exception {
         mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, alice, 
"mailbox");

http://git-wip-us.apache.org/repos/asf/james-project/blob/a345a328/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
index 0dd14a1..f1e94ce 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
@@ -51,6 +51,7 @@ public class FilterCondition implements Filter {
         private Boolean isFlagged;
         private Boolean isUnread;
         private Boolean isAnswered;
+        private Boolean isForwarded;
         private Boolean isDraft;
         private Boolean hasAttachment;
         private String text;
@@ -146,6 +147,11 @@ public class FilterCondition implements Filter {
             return this;
         }
 
+        public Builder isForwarded(boolean isForwarded) {
+            this.isForwarded = isForwarded;
+            return this;
+        }
+
         public Builder hasAttachment(boolean hasAttachment) {
             this.hasAttachment = hasAttachment;
             return this;
@@ -200,7 +206,8 @@ public class FilterCondition implements Filter {
             Preconditions.checkArgument(!hasKeyword.isPresent() || (new 
Keyword(hasKeyword.get()) != null), "hasKeyword is not valid");
             Preconditions.checkArgument(!notKeyword.isPresent() || (new 
Keyword(notKeyword.get()) != null), "notKeyword is not valid");
             return new FilterCondition(inMailboxes, notInMailboxes, 
Optional.ofNullable(before), Optional.ofNullable(after), 
Optional.ofNullable(minSize), Optional.ofNullable(maxSize),
-                    Optional.ofNullable(isFlagged), 
Optional.ofNullable(isUnread), Optional.ofNullable(isAnswered), 
Optional.ofNullable(isDraft), Optional.ofNullable(hasAttachment),
+                    Optional.ofNullable(isFlagged), 
Optional.ofNullable(isUnread), Optional.ofNullable(isAnswered), 
Optional.ofNullable(isDraft), Optional.ofNullable(isForwarded),
+                    Optional.ofNullable(hasAttachment),
                     Optional.ofNullable(text), Optional.ofNullable(from), 
Optional.ofNullable(to), Optional.ofNullable(cc), Optional.ofNullable(bcc), 
Optional.ofNullable(subject),
                     Optional.ofNullable(body), 
Optional.ofNullable(attachments), Optional.ofNullable(header), hasKeyword, 
notKeyword);
         }
@@ -216,6 +223,7 @@ public class FilterCondition implements Filter {
     private final Optional<Boolean> isUnread;
     private final Optional<Boolean> isAnswered;
     private final Optional<Boolean> isDraft;
+    private final Optional<Boolean> isForwarded;
     private final Optional<Boolean> hasAttachment;
     private final Optional<String> text;
     private final Optional<String> from;
@@ -230,7 +238,8 @@ public class FilterCondition implements Filter {
     private final Optional<String> notKeyword;
 
     @VisibleForTesting FilterCondition(Optional<List<String>> inMailboxes, 
Optional<List<String>> notInMailboxes, Optional<ZonedDateTime> before, 
Optional<ZonedDateTime> after, Optional<Integer> minSize, Optional<Integer> 
maxSize,
-                                       Optional<Boolean> isFlagged, 
Optional<Boolean> isUnread, Optional<Boolean> isAnswered, Optional<Boolean> 
isDraft, Optional<Boolean> hasAttachment,
+                                       Optional<Boolean> isFlagged, 
Optional<Boolean> isUnread, Optional<Boolean> isAnswered, Optional<Boolean> 
isDraft, Optional<Boolean> isForwarded,
+                                       Optional<Boolean> hasAttachment,
                                        Optional<String> text, Optional<String> 
from, Optional<String> to, Optional<String> cc, Optional<String> bcc, 
Optional<String> subject,
                                        Optional<String> body, Optional<String> 
attachments, Optional<Header> header, Optional<String> hasKeyword, 
Optional<String> notKeyword) {
 
@@ -244,6 +253,7 @@ public class FilterCondition implements Filter {
         this.isUnread = isUnread;
         this.isAnswered = isAnswered;
         this.isDraft = isDraft;
+        this.isForwarded = isForwarded;
         this.hasAttachment = hasAttachment;
         this.text = text;
         this.from = from;
@@ -298,6 +308,10 @@ public class FilterCondition implements Filter {
         return isDraft;
     }
 
+    public Optional<Boolean> getIsForwarded() {
+        return isForwarded;
+    }
+
     public Optional<Boolean> getHasAttachment() {
         return hasAttachment;
     }
@@ -360,6 +374,7 @@ public class FilterCondition implements Filter {
                 && Objects.equals(this.isUnread, other.isUnread)
                 && Objects.equals(this.isAnswered, other.isAnswered)
                 && Objects.equals(this.isDraft, other.isDraft)
+                && Objects.equals(this.isForwarded, other.isForwarded)
                 && Objects.equals(this.hasAttachment, other.hasAttachment)
                 && Objects.equals(this.text, other.text)
                 && Objects.equals(this.from, other.from)
@@ -378,7 +393,7 @@ public class FilterCondition implements Filter {
 
     @Override
     public final int hashCode() {
-        return Objects.hash(inMailboxes, notInMailboxes, before, after, 
minSize, maxSize, isFlagged, isUnread, isAnswered, isDraft, hasAttachment,
+        return Objects.hash(inMailboxes, notInMailboxes, before, after, 
minSize, maxSize, isFlagged, isUnread, isAnswered, isDraft, isForwarded, 
hasAttachment,
                 text, from, to, cc, bcc, subject, body, attachments, header, 
hasKeyword, notKeyword);
     }
 
@@ -395,6 +410,7 @@ public class FilterCondition implements Filter {
         isUnread.ifPresent(x -> helper.add("isUnread", x));
         isAnswered.ifPresent(x -> helper.add("isAnswered", x));
         isDraft.ifPresent(x -> helper.add("isDraft", x));
+        isForwarded.ifPresent(x -> helper.add("isForwarded", x));
         hasAttachment.ifPresent(x -> helper.add("hasAttachment", x));
         text.ifPresent(x -> helper.add("text", x));
         from.ifPresent(x -> helper.add("from", x));

http://git-wip-us.apache.org/repos/asf/james-project/blob/a345a328/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
index d364b59..e0b9cc6 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
@@ -28,6 +28,7 @@ import org.apache.james.jmap.model.Filter;
 import org.apache.james.jmap.model.FilterCondition;
 import org.apache.james.jmap.model.FilterOperator;
 import org.apache.james.jmap.model.Keyword;
+import org.apache.james.jmap.model.Keywords;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.SearchQuery.AddressType;
 import org.apache.james.mailbox.model.SearchQuery.Criterion;
@@ -76,6 +77,7 @@ public class FilterToSearchQuery {
         filter.getIsDraft().ifPresent(isDraft -> 
searchQuery.andCriteria(SearchQuery.flag(Flag.DRAFT, isDraft)));
         filter.getIsFlagged().ifPresent(isFlagged -> 
searchQuery.andCriteria(SearchQuery.flag(Flag.FLAGGED, isFlagged)));
         filter.getIsUnread().ifPresent(isUnread -> 
searchQuery.andCriteria(SearchQuery.flag(Flag.SEEN, !isUnread)));
+        filter.getIsForwarded().ifPresent(isForwarded -> 
searchQuery.andCriteria(SearchQuery.flagSet(Keyword.FORWARDED.getFlagName(), 
isForwarded)));
         filter.getMaxSize().ifPresent(maxSize -> 
searchQuery.andCriteria(SearchQuery.sizeLessThan(maxSize)));
         filter.getMinSize().ifPresent(minSize -> 
searchQuery.andCriteria(SearchQuery.sizeGreaterThan(minSize)));
         filter.getHasAttachment().ifPresent(hasAttachment -> 
searchQuery.andCriteria(SearchQuery.hasAttachment(hasAttachment)));

http://git-wip-us.apache.org/repos/asf/james-project/blob/a345a328/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
index 828c94a..8cac964 100644
--- 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
@@ -85,6 +85,7 @@ public class FilterConditionTest {
         boolean isUnread = true;
         boolean isAnswered = true;
         boolean isDraft = true;
+        boolean isForwarded = true;
         boolean hasAttachment = true;
         String text = "text";
         String from = "sen...@james.org";
@@ -99,7 +100,7 @@ public class FilterConditionTest {
         Optional<String> notKeyword = Optional.of("$Flagged");
 
         FilterCondition expectedFilterCondition = new 
FilterCondition(Optional.of(ImmutableList.of("1")), 
Optional.of(ImmutableList.of("2")), Optional.of(before), Optional.of(after), 
Optional.of(minSize), Optional.of(maxSize),
-                Optional.of(isFlagged), Optional.of(isUnread), 
Optional.of(isAnswered), Optional.of(isDraft), Optional.of(hasAttachment), 
Optional.of(text), Optional.of(from), 
+                Optional.of(isFlagged), Optional.of(isUnread), 
Optional.of(isAnswered), Optional.of(isDraft), Optional.of(isForwarded), 
Optional.of(hasAttachment), Optional.of(text), Optional.of(from),
                 Optional.of(to), Optional.of(cc), Optional.of(bcc), 
Optional.of(subject), Optional.of(body), Optional.of(attachments), 
Optional.of(header),
                 hasKeyword, notKeyword);
 
@@ -114,6 +115,7 @@ public class FilterConditionTest {
                 .isUnread(isUnread)
                 .isAnswered(isAnswered)
                 .isDraft(isDraft)
+                .isForwarded(isForwarded)
                 .hasAttachment(hasAttachment)
                 .text(text)
                 .from(from)


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