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