You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2020/09/15 02:27:33 UTC

[james-project] 05/06: JAMES-3368 port KeywordsCombiner and KeywordsCombinerTest

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 c93af4fc309ec7258ed068f89b24412c401570cc
Author: duc91 <vd...@linagora.com>
AuthorDate: Wed Sep 9 18:42:24 2020 +0700

    JAMES-3368 port KeywordsCombiner and KeywordsCombinerTest
---
 server/protocols/jmap-rfc-8621/pom.xml             |  6 ++
 .../apache/james/jmap/model/KeywordsCombiner.scala | 43 +++++++++++
 .../james/jmap/model/KeywordsCombinerTest.scala    | 90 ++++++++++++++++++++++
 3 files changed, 139 insertions(+)

diff --git a/server/protocols/jmap-rfc-8621/pom.xml b/server/protocols/jmap-rfc-8621/pom.xml
index 617bee6..dbcc7bb 100644
--- a/server/protocols/jmap-rfc-8621/pom.xml
+++ b/server/protocols/jmap-rfc-8621/pom.xml
@@ -81,6 +81,12 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-util</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>metrics-tests</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/KeywordsCombiner.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/KeywordsCombiner.scala
new file mode 100644
index 0000000..95262cd
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/model/KeywordsCombiner.scala
@@ -0,0 +1,43 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.jmap.model
+
+import java.util.function.BinaryOperator
+
+object KeywordsCombiner {
+  private val KEYWORD_TO_INTERSECT = Set(Keyword.DRAFT)
+  private val KEYWORD_NOT_TO_UNION = KEYWORD_TO_INTERSECT
+}
+
+final case class KeywordsCombiner() extends BinaryOperator[Keywords] {
+  val keywordsFactory: KeywordsFactory = KeywordsFactory.LENIENT_KEYWORDS_FACTORY
+
+  override def apply(keywords: Keywords, keywords2: Keywords): Keywords =
+    keywordsFactory.fromSet(
+      keywords.getKeywords.union(keywords2.getKeywords).union(KeywordsCombiner.KEYWORD_NOT_TO_UNION)
+        .union(keywords.getKeywords.intersect(keywords2.getKeywords).intersect(KeywordsCombiner.KEYWORD_TO_INTERSECT)))
+
+  def union(set1: Set[Keyword], set2: Set[Keyword], exceptKeywords: List[Keyword]): Set[Keyword] =
+    set1.union(set2)
+      .filter((keyword: Keyword) => !exceptKeywords.contains(keyword))
+
+  def intersect(set1: Set[Keyword], set2: Set[Keyword], forKeywords: List[Keyword]): Set[Keyword] =
+    set1.intersect(set2)
+      .filter(forKeywords.contains)
+}
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/KeywordsCombinerTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/KeywordsCombinerTest.scala
new file mode 100644
index 0000000..0fec305
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/model/KeywordsCombinerTest.scala
@@ -0,0 +1,90 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ * http://www.apache.org/licenses/LICENSE-2.0                   *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ * **************************************************************/
+
+package org.apache.james.jmap.model
+
+import org.apache.james.jmap.model.KeywordsFactory.LENIENT_KEYWORDS_FACTORY
+import org.apache.james.util.CommutativityChecker
+import org.assertj.core.api.Assertions.assertThat
+import org.scalatest.matchers.must.Matchers
+import org.scalatest.wordspec.AnyWordSpec
+import scala.jdk.CollectionConverters._
+
+class KeywordsCombinerTest extends AnyWordSpec with Matchers {
+  "apply should union seen keyword" in {
+      val keywordsCombiner = KeywordsCombiner()
+    assertThat(keywordsCombiner.apply(Keywords.DEFAULT_VALUE, LENIENT_KEYWORDS_FACTORY.from(Keyword.SEEN)))
+      .isEqualTo(LENIENT_KEYWORDS_FACTORY.from(Keyword.SEEN))
+  }
+
+  "apply should union answered keyword" in {
+    val keywordsCombiner = KeywordsCombiner()
+    assertThat(keywordsCombiner.apply(Keywords.DEFAULT_VALUE, LENIENT_KEYWORDS_FACTORY.from(Keyword.ANSWERED))).isEqualTo(LENIENT_KEYWORDS_FACTORY.from(Keyword.ANSWERED))
+  }
+
+  "apply should union flagged keyword" in {
+    val keywordsCombiner = KeywordsCombiner()
+    assertThat(keywordsCombiner.apply(Keywords.DEFAULT_VALUE, LENIENT_KEYWORDS_FACTORY.from(Keyword.FLAGGED))).isEqualTo(LENIENT_KEYWORDS_FACTORY.from(Keyword.FLAGGED))
+  }
+
+  "apply should intersect draft keyword" in {
+    val keywordsCombiner = KeywordsCombiner()
+    assertThat(keywordsCombiner.apply(Keywords.DEFAULT_VALUE, LENIENT_KEYWORDS_FACTORY.from(Keyword.DRAFT))).isEqualTo(Keywords.DEFAULT_VALUE)
+  }
+
+  "apply should union custom keyword" in {
+    val keywordsCombiner = KeywordsCombiner()
+    val customKeyword = Keyword.of("$Any")
+    assertThat(keywordsCombiner.apply(Keywords.DEFAULT_VALUE, LENIENT_KEYWORDS_FACTORY.from(customKeyword.get))).isEqualTo(LENIENT_KEYWORDS_FACTORY.from(customKeyword.get))
+  }
+
+  "apply should accept empty as a zeroValue" in {
+    val keywordsCombiner = KeywordsCombiner()
+    assertThat(keywordsCombiner.apply(Keywords.DEFAULT_VALUE, Keywords.DEFAULT_VALUE)).isEqualTo(Keywords.DEFAULT_VALUE)
+  }
+
+  "apply should union different flags" in {
+    val keywordsCombiner = KeywordsCombiner()
+    assertThat(keywordsCombiner.apply(LENIENT_KEYWORDS_FACTORY.from(Keyword.FLAGGED), LENIENT_KEYWORDS_FACTORY.from(Keyword.ANSWERED))).isEqualTo(LENIENT_KEYWORDS_FACTORY.from(Keyword.FLAGGED, Keyword.ANSWERED))
+  }
+
+  "keywords combiner should be commutative" in {
+    val allKeyword = LENIENT_KEYWORDS_FACTORY.from(
+      Keyword.ANSWERED,
+      Keyword.DELETED,
+      Keyword.DRAFT,
+      Keyword.FLAGGED,
+      Keyword.SEEN,
+      Keyword.of("$Forwarded").get,
+      Keyword.of("$Any").get)
+
+    val values:Set[Keywords] = Set(
+      LENIENT_KEYWORDS_FACTORY.from(Keyword.ANSWERED),
+      LENIENT_KEYWORDS_FACTORY.from(Keyword.DELETED),
+      LENIENT_KEYWORDS_FACTORY.from(Keyword.DRAFT),
+      LENIENT_KEYWORDS_FACTORY.from(Keyword.FLAGGED),
+      LENIENT_KEYWORDS_FACTORY.from(Keyword.SEEN),
+      LENIENT_KEYWORDS_FACTORY.from(),
+      LENIENT_KEYWORDS_FACTORY.from(Keyword.of("$Forwarded").get),
+      LENIENT_KEYWORDS_FACTORY.from(Keyword.of("$Any").get),
+      allKeyword)
+
+    assertThat(new CommutativityChecker[Keywords](values.asJava, KeywordsCombiner()).findNonCommutativeInput).isEmpty()
+  }
+}
\ No newline at end of file


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