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

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


The following commit(s) were added to refs/heads/master by this push:
     new 1f039b84a4 [FIX] JMAP Email/get: combine read level after attachments 
(#3232)
1f039b84a4 is described below

commit 1f039b84a48557055edf5793fe40e05440044441
Author: Benoit TELLIER <[email protected]>
AuthorDate: Mon Oct 5 11:37:05 2026 +0200

    [FIX] JMAP Email/get: combine read level after attachments (#3232)
    
    Email/get failed with serverFail (NotImplementedError) whenever
    "attachments" was followed by another property, as ReadLevel.combine
    did not handle FastViewWithAttachmentsMetadataReadLevel as first
    argument.
---
 .../scala/org/apache/james/jmap/mail/Email.scala   |  5 +-
 .../org/apache/james/jmap/mail/ReadLevelTest.scala | 58 ++++++++++++++++++++++
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
index c180a11d9d..d9ca33e15b 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/Email.scala
@@ -194,7 +194,10 @@ object ReadLevel {
       case FastViewWithAttachmentsMetadataReadLevel => 
FastViewWithAttachmentsMetadataReadLevel
       case _ => FastViewReadLevel
     }
-    case _ => throw new NotImplementedError()
+    case FastViewWithAttachmentsMetadataReadLevel => readLevel2 match {
+      case FullReadLevel => FullReadLevel
+      case _ => FastViewWithAttachmentsMetadataReadLevel
+    }
   }
 }
 
diff --git 
a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/mail/ReadLevelTest.scala
 
b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/mail/ReadLevelTest.scala
new file mode 100644
index 0000000000..7abd76209a
--- /dev/null
+++ 
b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/mail/ReadLevelTest.scala
@@ -0,0 +1,58 @@
+/****************************************************************
+ * 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.mail
+
+import org.scalatest.matchers.must.Matchers
+import org.scalatest.wordspec.AnyWordSpec
+
+class ReadLevelTest extends AnyWordSpec with Matchers {
+  private val readLevelsByIncreasingCost: Seq[ReadLevel] = Seq(
+    MetadataReadLevel,
+    HeaderReadLevel,
+    FastViewReadLevel,
+    FastViewWithAttachmentsMetadataReadLevel,
+    FullReadLevel)
+
+  private val pairs: Seq[(ReadLevel, ReadLevel)] = for {
+    readLevel1 <- readLevelsByIncreasingCost
+    readLevel2 <- readLevelsByIncreasingCost
+  } yield (readLevel1, readLevel2)
+
+  private def mostExpensive(readLevel1: ReadLevel, readLevel2: ReadLevel): 
ReadLevel =
+    Seq(readLevel1, readLevel2).maxBy(readLevelsByIncreasingCost.indexOf)
+
+  "combine" should {
+    "return the most expensive read level" in {
+      pairs.foreach { case (readLevel1, readLevel2) =>
+        ReadLevel.combine(readLevel1, readLevel2) must 
equal(mostExpensive(readLevel1, readLevel2))
+      }
+    }
+
+    "be commutative" in {
+      pairs.foreach { case (readLevel1, readLevel2) =>
+        ReadLevel.combine(readLevel1, readLevel2) must 
equal(ReadLevel.combine(readLevel2, readLevel1))
+      }
+    }
+
+    "support attachments followed by another property" in {
+      ReadLevel.combine(FastViewWithAttachmentsMetadataReadLevel, 
MetadataReadLevel) must equal(FastViewWithAttachmentsMetadataReadLevel)
+    }
+  }
+}


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

Reply via email to