This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit ff5a09a25880ca7482d679c4104ecb529eddbecb
Author: Rene Cordier <[email protected]>
AuthorDate: Wed Sep 23 14:49:03 2020 +0700

    JAMES-3384 text, from, to, cc, bcc, subject, header, body parameters are 
not yet supported for filtering on Email/query
---
 .../contract/EmailQueryMethodContract.scala        | 49 +++++++++++++++++-
 .../james/jmap/json/EmailQuerySerializer.scala     | 10 +++-
 .../org/apache/james/jmap/mail/EmailQuery.scala    | 18 ++++++-
 .../james/jmap/utils/search/MailboxFilter.scala    | 59 +++++++++++++++++++++-
 4 files changed, 132 insertions(+), 4 deletions(-)

diff --git 
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
index 0040ae2..e521a7f 100644
--- 
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
+++ 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala
@@ -920,7 +920,14 @@ trait EmailQueryMethodContract {
   @ValueSource(strings = Array(
     "allInThreadHaveKeyword",
     "someInThreadHaveKeyword",
-    "noneInThreadHaveKeyword"
+    "noneInThreadHaveKeyword",
+    "text",
+    "from",
+    "to",
+    "cc",
+    "bcc",
+    "subject",
+    "body"
   ))
   def 
listMailsShouldReturnUnsupportedFilterWhenValidButUnsupported(unsupportedFilter:
 String): Unit = {
     val request =
@@ -961,6 +968,46 @@ trait EmailQueryMethodContract {
        """)
   }
 
+  @Test
+  def listMailsShouldReturnUnsupportedFilterWhenHeaderFilter(): Unit = {
+    val request =
+      s"""{
+         |  "using": [
+         |    "urn:ietf:params:jmap:core",
+         |    "urn:ietf:params:jmap:mail"],
+         |  "methodCalls": [[
+         |    "Email/query",
+         |    {
+         |      "accountId": 
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+         |      "filter" : {
+         |        "header": ["header1", "header2"]
+         |      }
+         |    },
+         |    "c1"]]
+         |}""".stripMargin
+
+    val response = `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(request)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .contentType(JSON)
+      .extract
+      .body
+      .asString
+
+    assertThatJson(response)
+      .inPath("$.methodResponses[0][1]")
+      .isEqualTo(s"""
+       {
+          "type": "unsupportedFilter",
+          "description": "The filter header is syntactically valid, but the 
server cannot process it. If the filter was the result of a user’s search 
input, the client SHOULD suggest that the user simplify their search."
+       }
+       """)
+  }
+
   @ParameterizedTest
   @ValueSource(strings = Array(
     "true",
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala
index 9d86b2b..e2dce1b 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/EmailQuerySerializer.scala
@@ -20,7 +20,7 @@
 package org.apache.james.jmap.json
 
 import javax.inject.Inject
-import org.apache.james.jmap.mail.{AllInThreadHaveKeywordSortProperty, Anchor, 
AnchorOffset, CollapseThreads, Collation, Comparator, EmailQueryRequest, 
EmailQueryResponse, FilterCondition, FromSortProperty, HasAttachment, 
HasKeywordSortProperty, IsAscending, ReceivedAtSortProperty, SizeSortProperty, 
SomeInThreadHaveKeywordSortProperty, SortProperty, SubjectSortProperty, 
ToSortProperty}
+import org.apache.james.jmap.mail.{AllInThreadHaveKeywordSortProperty, Anchor, 
AnchorOffset, Bcc, Body, Cc, CollapseThreads, Collation, Comparator, 
EmailQueryRequest, EmailQueryResponse, FilterCondition, From, FromSortProperty, 
HasAttachment, HasKeywordSortProperty, Header, IsAscending, 
ReceivedAtSortProperty, SizeSortProperty, SomeInThreadHaveKeywordSortProperty, 
SortProperty, Subject, SubjectSortProperty, Text, To, ToSortProperty}
 import org.apache.james.jmap.model.{AccountId, CanCalculateChanges, Keyword, 
LimitUnparsed, PositionUnparsed, QueryState}
 import org.apache.james.mailbox.model.{MailboxId, MessageId}
 import play.api.libs.json._
@@ -49,6 +49,14 @@ class EmailQuerySerializer @Inject()(mailboxIdFactory: 
MailboxId.Factory) {
     case _ => JsError("Expecting keywords to be represented by a JsString")
   }
   private implicit val hasAttachmentReads: Reads[HasAttachment] = 
Json.valueReads[HasAttachment]
+  private implicit val textReads: Reads[Text] = Json.valueReads[Text]
+  private implicit val fromReads: Reads[From] = Json.valueReads[From]
+  private implicit val toReads: Reads[To] = Json.valueReads[To]
+  private implicit val ccReads: Reads[Cc] = Json.valueReads[Cc]
+  private implicit val bccReads: Reads[Bcc] = Json.valueReads[Bcc]
+  private implicit val subjectReads: Reads[Subject] = Json.valueReads[Subject]
+  private implicit val headerReads: Reads[Header] = Json.valueReads[Header]
+  private implicit val bodyReads: Reads[Body] = Json.valueReads[Body]
   private implicit val filterConditionReads: Reads[FilterCondition] = 
Json.reads[FilterCondition]
   private implicit val limitUnparsedReads: Reads[LimitUnparsed] = 
Json.valueReads[LimitUnparsed]
   private implicit val CanCalculateChangesFormat: Format[CanCalculateChanges] 
= Json.valueFormat[CanCalculateChanges]
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala
index 4856bbc..6e5c308 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/EmailQuery.scala
@@ -31,6 +31,14 @@ case class UnsupportedSortException(unsupportedSort: String) 
extends Unsupported
 case class UnsupportedFilterException(unsupportedFilter: String) extends 
UnsupportedOperationException
 case class UnsupportedRequestParameterException(unsupportedParam: String) 
extends UnsupportedOperationException
 
+case class Text(value: String) extends AnyVal
+case class From(value: String) extends AnyVal
+case class To(value: String) extends AnyVal
+case class Cc(value: String) extends AnyVal
+case class Bcc(value: String) extends AnyVal
+case class Body(value: String) extends AnyVal
+case class Header(value: String) extends AnyVal
+
 case class FilterCondition(inMailbox: Option[MailboxId],
                            inMailboxOtherThan: Option[Seq[MailboxId]],
                            before: Option[UTCDate],
@@ -42,7 +50,15 @@ case class FilterCondition(inMailbox: Option[MailboxId],
                            hasAttachment: Option[HasAttachment],
                            allInThreadHaveKeyword: Option[Keyword],
                            someInThreadHaveKeyword: Option[Keyword],
-                           noneInThreadHaveKeyword: Option[Keyword])
+                           noneInThreadHaveKeyword: Option[Keyword],
+                           text: Option[Text],
+                           from: Option[From],
+                           to: Option[To],
+                           cc: Option[Cc],
+                           bcc: Option[Bcc],
+                           subject: Option[Subject],
+                           header: Option[Set[Header]],
+                           body: Option[Body])
 
 case class EmailQueryRequest(accountId: AccountId,
                              position: Option[PositionUnparsed],
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala
index 73fe224..3ef1239 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/utils/search/MailboxFilter.scala
@@ -61,7 +61,8 @@ object MailboxFilter {
   object QueryFilter {
     def buildQuery(request: EmailQueryRequest): 
Either[UnsupportedFilterException, SearchQuery.Builder] = {
       List(ReceivedBefore, ReceivedAfter, HasAttachment, HasKeyWord, 
NotKeyWord, MinSize, MaxSize,
-           AllInThreadHaveKeyword, NoneInThreadHaveKeyword, 
SomeInThreadHaveKeyword)
+           AllInThreadHaveKeyword, NoneInThreadHaveKeyword, 
SomeInThreadHaveKeyword, Text, From,
+           To, Cc, Bcc, Subject, Header, Body)
         .foldLeftM(new SearchQuery.Builder())((builder, filter) => 
filter.toQuery(builder, request))
     }
   }
@@ -163,4 +164,60 @@ object MailboxFilter {
         case None => Right(builder)
       }
   }
+  case object Text extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.text) match {
+        case Some(_) => Left(UnsupportedFilterException("text"))
+        case None => Right(builder)
+      }
+  }
+  case object From extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.from) match {
+        case Some(_) => Left(UnsupportedFilterException("from"))
+        case None => Right(builder)
+      }
+  }
+  case object To extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.to) match {
+        case Some(_) => Left(UnsupportedFilterException("to"))
+        case None => Right(builder)
+      }
+  }
+  case object Cc extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.cc) match {
+        case Some(_) => Left(UnsupportedFilterException("cc"))
+        case None => Right(builder)
+      }
+  }
+  case object Bcc extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.bcc) match {
+        case Some(_) => Left(UnsupportedFilterException("bcc"))
+        case None => Right(builder)
+      }
+  }
+  case object Subject extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.subject) match {
+        case Some(_) => Left(UnsupportedFilterException("subject"))
+        case None => Right(builder)
+      }
+  }
+  case object Header extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.header) match {
+        case Some(_) => Left(UnsupportedFilterException("header"))
+        case None => Right(builder)
+      }
+  }
+  case object Body extends QueryFilter {
+    override def toQuery(builder: SearchQuery.Builder, request: 
EmailQueryRequest): Either[UnsupportedFilterException, SearchQuery.Builder] =
+      request.filter.flatMap(_.body) match {
+        case Some(_) => Left(UnsupportedFilterException("body"))
+        case None => Right(builder)
+      }
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to