You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2018/12/19 04:10:31 UTC

[05/13] james-project git commit: MAILBOX-362 Serialization for MailboxACLUpdated event

MAILBOX-362 Serialization for MailboxACLUpdated event


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

Branch: refs/heads/master
Commit: 2d5abee7b6cb67eea84a5f6d2f0cb6d68ccbf039
Parents: 8eaf1f6
Author: datph <dp...@linagora.com>
Authored: Tue Dec 18 11:12:02 2018 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Wed Dec 19 10:55:53 2018 +0700

----------------------------------------------------------------------
 .../apache/james/mailbox/model/MailboxACL.java  |   4 +
 .../org/apache/james/event/json/DTOs.scala      |  14 +-
 .../james/event/json/EventSerializer.scala      |  40 +-
 ...MailboxACLUpdatedEventSerializationTest.java | 985 +++++++++++++++++++
 4 files changed, 1039 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2d5abee7/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
index 3bdf826..d02d6ff 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MailboxACL.java
@@ -175,6 +175,10 @@ public class MailboxACL {
                 .except(new Rfc4314Rights(rights));
         }
 
+        public static Rfc4314Rights deserialize(String serialized) throws UnsupportedRightException {
+            return new Rfc4314Rights(serialized);
+        }
+
         private static final char c_ObsoleteCreate = 'c';
         private static final char d_ObsoleteDelete = 'd';
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/2d5abee7/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
----------------------------------------------------------------------
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
index 8d8af9e..3e04d1c 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/DTOs.scala
@@ -20,11 +20,18 @@
 package org.apache.james.event.json
 
 import org.apache.james.core.quota.QuotaValue
-import org.apache.james.mailbox.model.{MailboxPath => JavaMailboxPath, Quota => JavaQuota}
+import org.apache.james.mailbox.acl.{ACLDiff => JavaACLDiff}
+import org.apache.james.mailbox.model.{MailboxACL, MailboxPath => JavaMailboxPath, Quota => JavaQuota}
 
 import scala.collection.JavaConverters._
 
 object DTOs {
+  object ACLDiff {
+    def fromJava(javaACLDiff: JavaACLDiff): ACLDiff = ACLDiff(
+      javaACLDiff.getOldACL.getEntries.asScala.toMap,
+      javaACLDiff.getNewACL.getEntries.asScala.toMap)
+  }
+
   object MailboxPath {
     def fromJava(javaMailboxPath: JavaMailboxPath): MailboxPath = MailboxPath(
       Option(javaMailboxPath.getNamespace),
@@ -39,6 +46,11 @@ object DTOs {
       limits = java.getLimitByScope.asScala.toMap)
   }
 
+  case class ACLDiff(oldACL: Map[MailboxACL.EntryKey, MailboxACL.Rfc4314Rights],
+                     newACL: Map[MailboxACL.EntryKey, MailboxACL.Rfc4314Rights]) {
+    def toJava: JavaACLDiff = new JavaACLDiff(new MailboxACL(oldACL.asJava), new MailboxACL(newACL.asJava))
+  }
+
   case class MailboxPath(namespace: Option[String], user: Option[String], name: String) {
     def toJava: JavaMailboxPath = new JavaMailboxPath(namespace.orNull, user.orNull, name)
   }

http://git-wip-us.apache.org/repos/asf/james-project/blob/2d5abee7/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
----------------------------------------------------------------------
diff --git a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
index 544859b..7dcffbc 100644
--- a/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
+++ b/mailbox/event/json/src/main/scala/org/apache/james/event/json/EventSerializer.scala
@@ -25,10 +25,10 @@ import java.util.Optional
 import julienrf.json.derived
 import org.apache.james.core.quota.{QuotaCount, QuotaSize, QuotaValue}
 import org.apache.james.core.{Domain, User}
-import org.apache.james.event.json.DTOs.{MailboxPath, Quota}
-import org.apache.james.mailbox.MailboxListener.{MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
+import org.apache.james.event.json.DTOs.{ACLDiff, MailboxPath, Quota}
+import org.apache.james.mailbox.MailboxListener.{MailboxACLUpdated => JavaMailboxACLUpdated, MailboxAdded => JavaMailboxAdded, MailboxDeletion => JavaMailboxDeletion, MailboxRenamed => JavaMailboxRenamed, QuotaUsageUpdatedEvent => JavaQuotaUsageUpdatedEvent}
 import org.apache.james.mailbox.MailboxSession.SessionId
-import org.apache.james.mailbox.model.{MailboxId, QuotaRoot, Quota => JavaQuota}
+import org.apache.james.mailbox.model.{MailboxId, QuotaRoot, MailboxACL => JavaMailboxACL, Quota => JavaQuota}
 import org.apache.james.mailbox.{Event => JavaEvent}
 import play.api.libs.json.{JsError, JsNull, JsNumber, JsObject, JsResult, JsString, JsSuccess, Json, OFormat, Reads, Writes}
 
@@ -57,6 +57,10 @@ private object DTO {
       totalDeletedSize,
       mailboxId)
   }
+
+  case class MailboxACLUpdated(sessionId: SessionId, user: User, mailboxPath: MailboxPath, aclDiff: ACLDiff, mailboxId: MailboxId) extends Event {
+    override def toJava: JavaEvent = new JavaMailboxACLUpdated(sessionId, user, mailboxPath.toJava, aclDiff.toJava, mailboxId)
+  }
 }
 
 private object ScalaConverter {
@@ -89,11 +93,19 @@ private object ScalaConverter {
     totalDeletedSize = event.getTotalDeletedSize,
     mailboxId = event.getMailboxId)
 
+  private def toScala(event: JavaMailboxACLUpdated): DTO.MailboxACLUpdated = DTO.MailboxACLUpdated(
+    sessionId = event.getSessionId,
+    user = event.getUser,
+    mailboxPath = MailboxPath.fromJava(event.getMailboxPath),
+    aclDiff = ACLDiff.fromJava(event.getAclDiff),
+    mailboxId = event.getMailboxId)
+
   def toScala(javaEvent: JavaEvent): Event = javaEvent match {
     case e: JavaQuotaUsageUpdatedEvent => toScala(e)
     case e: JavaMailboxAdded => toScala(e)
     case e: JavaMailboxRenamed => toScala(e)
     case e: JavaMailboxDeletion => toScala(e)
+    case e: JavaMailboxACLUpdated => toScala(e)
     case _ => throw new RuntimeException("no Scala convertion known")
   }
 }
@@ -108,7 +120,18 @@ private class JsonSerialize(mailboxIdFactory: MailboxId.Factory) {
   implicit val mailboxPathWrites: Writes[MailboxPath] = Json.writes[MailboxPath]
   implicit val mailboxIdWrites: Writes[MailboxId] = value => JsString(value.serialize())
   implicit val sessionIdWrites: Writes[SessionId] = value => JsNumber(value.getValue)
+  implicit val aclEntryKeyWrites: Writes[JavaMailboxACL.EntryKey] = value => JsString(value.serialize())
+  implicit val aclRightsWrites: Writes[JavaMailboxACL.Rfc4314Rights] = value => JsString(value.serialize())
+  implicit val aclDiffWrites: Writes[ACLDiff] = Json.writes[ACLDiff]
 
+  implicit val aclEntryKeyReads: Reads[JavaMailboxACL.EntryKey] = {
+    case JsString(keyAsString) => JsSuccess(JavaMailboxACL.EntryKey.deserialize(keyAsString))
+    case _ => JsError()
+  }
+  implicit val aclRightsReads: Reads[JavaMailboxACL.Rfc4314Rights] = {
+    case JsString(rightsAsString) => JsSuccess(JavaMailboxACL.Rfc4314Rights.deserialize(rightsAsString))
+    case _ => JsError()
+  }
   implicit val userReads: Reads[User] = {
     case JsString(userAsString) => JsSuccess(User.fromUsername(userAsString))
     case _ => JsError()
@@ -150,9 +173,20 @@ private class JsonSerialize(mailboxIdFactory: MailboxId.Factory) {
       JsObject(m.map { case (k, v) => (k.toString, vr.writes(v)) }.toSeq)
     }
 
+  implicit def scopeMapReadsACL[V](implicit vr: Reads[V]): Reads[Map[JavaMailboxACL.EntryKey, V]] =
+    Reads.mapReads[JavaMailboxACL.EntryKey, V] { str =>
+      Json.fromJson[JavaMailboxACL.EntryKey](JsString(str))
+    }
+
+  implicit def scopeMapWriteACL[V](implicit vr: Writes[V]): Writes[Map[JavaMailboxACL.EntryKey, V]] =
+    (m: Map[JavaMailboxACL.EntryKey, V]) => {
+      JsObject(m.map { case (k, v) => (k.toString, vr.writes(v)) }.toSeq)
+    }
+
   implicit val quotaCReads: Reads[Quota[QuotaCount]] = Json.reads[Quota[QuotaCount]]
   implicit val quotaSReads: Reads[Quota[QuotaSize]] = Json.reads[Quota[QuotaSize]]
   implicit val mailboxPathReads: Reads[MailboxPath] = Json.reads[MailboxPath]
+  implicit val aclDiffReads: Reads[ACLDiff] = Json.reads[ACLDiff]
 
   implicit val eventOFormat: OFormat[Event] = derived.oformat()
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/2d5abee7/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
new file mode 100644
index 0000000..ceed360
--- /dev/null
+++ b/mailbox/event/json/src/test/java/org/apache/james/event/json/MailboxACLUpdatedEventSerializationTest.java
@@ -0,0 +1,985 @@
+/****************************************************************
+ * 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.event.json;
+
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.NoSuchElementException;
+
+import org.apache.james.core.User;
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.acl.ACLDiff;
+import org.apache.james.mailbox.exception.UnsupportedRightException;
+import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.TestId;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+
+class MailboxACLUpdatedEventSerializationTest {
+
+    private static final User USER = User.fromUsername("user");
+    private static final MailboxACL.EntryKey ENTRY_KEY = org.apache.james.mailbox.model.MailboxACL.EntryKey.createGroupEntryKey("any", false);
+    private static final MailboxACL.Rfc4314Rights RIGHTS = new MailboxACL.Rfc4314Rights(MailboxACL.Right.Administer, MailboxACL.Right.Read);
+    private static final EventSerializer EVENT_SERIALIZER = new EventSerializer(new TestId.Factory());
+    private static final MailboxACL MAILBOX_ACL = new MailboxACL(
+        new MailboxACL.Entry(ENTRY_KEY, RIGHTS),
+        new MailboxACL.Entry(MailboxACL.EntryKey.createUserEntryKey("alice", true),
+            new MailboxACL.Rfc4314Rights(MailboxACL.Right.Insert)));
+
+    private static final MailboxListener.MailboxACLUpdated MAILBOX_ACL_UPDATED = new MailboxListener.MailboxACLUpdated(
+                MailboxSession.SessionId.of(6),
+                USER,
+                new MailboxPath(MailboxConstants.USER_NAMESPACE, "bob", "mailboxName"),
+                ACLDiff.computeDiff(MailboxACL.EMPTY, MAILBOX_ACL),
+                TestId.of(23));
+
+    private static final String MAILBOX_ACL_UPDATED_JSON = "{" +
+        "  \"MailboxACLUpdated\":{" +
+        "    \"mailboxPath\":{" +
+        "       \"namespace\":\"#private\"," +
+        "       \"user\":\"bob\"," +
+        "       \"name\":\"mailboxName\"" +
+        "      }," +
+        "    \"aclDiff\":{" +
+        "       \"oldACL\":{}," +
+        "       \"newACL\":{\"$any\":\"ar\", \"-alice\":\"i\"}}," +
+        "    \"mailboxId\":\"23\"," +
+        "    \"sessionId\":6," +
+        "    \"user\":\"user\"" +
+        "   }" +
+        "}";
+
+    @Test
+    void mailboxACLUpdatedShouldBeSerialized() {
+        assertThatJson(EVENT_SERIALIZER.toJson(MAILBOX_ACL_UPDATED))
+            .isEqualTo(MAILBOX_ACL_UPDATED_JSON);
+    }
+
+    @Test
+    void mailboxACLUpdatedShouldBeDeserialized() {
+        assertThat(EVENT_SERIALIZER.fromJson(MAILBOX_ACL_UPDATED_JSON).get())
+            .isEqualTo(MAILBOX_ACL_UPDATED);
+    }
+
+    @Nested
+    class NullUserInMailboxPath {
+        private final String NULL_USER = null;
+        private static final String JSON_2 = "{" +
+            "  \"MailboxACLUpdated\":{" +
+            "    \"mailboxPath\":{" +
+            "       \"namespace\":\"#private\"," +
+            "       \"name\":\"mailboxName\"" +
+            "      }," +
+            "    \"aclDiff\":{" +
+            "       \"oldACL\":{}," +
+            "       \"newACL\":{\"$any\":\"ar\"}}," +
+            "    \"mailboxId\":\"23\"," +
+            "    \"sessionId\":6," +
+            "    \"user\":\"user\"" +
+            "   }" +
+            "}";
+
+        private final MailboxACL MAILBOX_ACL= new MailboxACL(
+                new MailboxACL.Entry(ENTRY_KEY, RIGHTS));
+
+        private final MailboxListener.MailboxACLUpdated UPDATED_EVENT = new MailboxListener.MailboxACLUpdated(
+                MailboxSession.SessionId.of(6),
+                USER,
+                new MailboxPath(MailboxConstants.USER_NAMESPACE, NULL_USER, "mailboxName"),
+                ACLDiff.computeDiff(MailboxACL.EMPTY, MAILBOX_ACL),
+                TestId.of(23));
+
+        @Test
+        void mailboxACLUpdatedShouldBeWellSerializedWithNullUser() {
+            assertThatJson(EVENT_SERIALIZER.toJson(UPDATED_EVENT))
+                .isEqualTo(JSON_2);
+        }
+
+        @Test
+        void mailboxACLUpdatedShouldBeWellDeSerializedWithNullUser() {
+            assertThat(EVENT_SERIALIZER.fromJson(JSON_2).get())
+                .isEqualTo(UPDATED_EVENT);
+        }
+    }
+
+    @Nested
+    class NullNameSpaceInMailboxPath {
+
+        private final MailboxACL MAILBOX_ACL = new MailboxACL(
+            new MailboxACL.Entry(ENTRY_KEY, RIGHTS));
+
+        private final MailboxListener.MailboxACLUpdated UPDATED_EVENT = new MailboxListener.MailboxACLUpdated(
+            MailboxSession.SessionId.of(6),
+            USER,
+            new MailboxPath(MailboxConstants.USER_NAMESPACE, "bob", "mailboxName"),
+            ACLDiff.computeDiff(MailboxACL.EMPTY, MAILBOX_ACL),
+            TestId.of(23));
+
+        @Test
+        void mailboxAddedShouldBeWellDeSerializedWhenMissingNameSpace() {
+            assertThat(EVENT_SERIALIZER.fromJson(
+                "{" +
+                "  \"MailboxACLUpdated\":{" +
+                "    \"mailboxPath\":{" +
+                "       \"user\": \"bob\"," +
+                "       \"name\":\"mailboxName\"" +
+                "      }," +
+                "    \"aclDiff\":{" +
+                "       \"oldACL\":{}," +
+                "       \"newACL\":{\"$any\":\"ar\"}}," +
+                "    \"mailboxId\":\"23\"," +
+                "    \"sessionId\":6," +
+                "    \"user\":\"user\"" +
+                "   }" +
+                "}").get())
+                .isEqualTo(UPDATED_EVENT);
+        }
+
+        @Test
+        void mailboxAddedShouldBeWellDeSerializedWhenNullNameSpace() {
+            assertThat(EVENT_SERIALIZER.fromJson(
+                "{" +
+                "  \"MailboxACLUpdated\":{" +
+                "    \"mailboxPath\":{" +
+                "       \"namespace\":null," +
+                "       \"user\": \"bob\"," +
+                "       \"name\":\"mailboxName\"" +
+                "      }," +
+                "    \"aclDiff\":{" +
+                "       \"oldACL\":{}," +
+                "       \"newACL\":{\"$any\":\"ar\"}}," +
+                "    \"mailboxId\":\"23\"," +
+                "    \"sessionId\":6," +
+                "    \"user\":\"user\"" +
+                "   }" +
+                "}").get())
+                .isEqualTo(UPDATED_EVENT);
+        }
+    }
+
+    @Nested
+    class EmptyRightInMailboxACL {
+
+        private final String jsonNullRight =
+            "{" +
+            "  \"MailboxACLUpdated\":{" +
+            "    \"mailboxPath\":{" +
+            "       \"namespace\":\"#private\"," +
+            "       \"user\":\"bob\"," +
+            "       \"name\":\"mailboxName\"" +
+            "      }," +
+            "    \"aclDiff\":{" +
+            "       \"oldACL\":{\"$any\":\"\"}," +
+            "       \"newACL\":{}}," +
+            "    \"mailboxId\":\"23\"," +
+            "    \"sessionId\":6," +
+            "    \"user\":\"user\"" +
+            "   }" +
+            "}";
+
+        private final MailboxACL mailboxACL = new MailboxACL(
+                new MailboxACL.Entry(ENTRY_KEY, new MailboxACL.Rfc4314Rights()));
+
+        private final MailboxListener.MailboxACLUpdated mailboxACLUpdated = new MailboxListener.MailboxACLUpdated(
+                MailboxSession.SessionId.of(6),
+                USER,
+                new MailboxPath(MailboxConstants.USER_NAMESPACE, "bob", "mailboxName"),
+                ACLDiff.computeDiff(mailboxACL, MailboxACL.EMPTY),
+                TestId.of(23));
+
+        @Test
+        void mailboxACLUpdatedShouldBeWellSerializedWithNullRight() {
+            assertThatJson(EVENT_SERIALIZER.toJson(mailboxACLUpdated))
+                .isEqualTo(jsonNullRight);
+        }
+
+        @Test
+        void mailboxACLUpdatedShouldBeWellDeSerializedWithNullUser() {
+            assertThat(EVENT_SERIALIZER.fromJson(jsonNullRight).get())
+                .isEqualTo(mailboxACLUpdated);
+        }
+    }
+
+    @Nested
+    class DoubleRightInMailboxACL {
+
+        private final String jsonDoubleRight =
+            "{" +
+            "  \"MailboxACLUpdated\":{" +
+            "    \"mailboxPath\":{" +
+            "       \"namespace\":\"#private\"," +
+            "       \"user\":\"bob\"," +
+            "       \"name\":\"mailboxName\"" +
+            "      }," +
+            "    \"aclDiff\":{" +
+            "       \"oldACL\":{\"$any\":\"aa\"}," +
+            "       \"newACL\":{}}," +
+            "    \"mailboxId\":\"23\"," +
+            "    \"sessionId\":6," +
+            "    \"user\":\"user\"" +
+            "   }" +
+            "}";
+
+        private final MailboxACL mailboxACL = new MailboxACL(
+            new MailboxACL.Entry(ENTRY_KEY, new MailboxACL.Rfc4314Rights(MailboxACL.Right.Administer)));
+
+        private final MailboxListener.MailboxACLUpdated mailboxACLUpdated = new MailboxListener.MailboxACLUpdated(
+            MailboxSession.SessionId.of(6),
+            USER,
+            new MailboxPath(MailboxConstants.USER_NAMESPACE, "bob", "mailboxName"),
+            ACLDiff.computeDiff(mailboxACL, MailboxACL.EMPTY),
+            TestId.of(23));
+
+        @Test
+        void mailboxACLUpdatedShouldBeWellSerializedWithNullRight() {
+            assertThatJson(EVENT_SERIALIZER.toJson(mailboxACLUpdated))
+                .isNotEqualTo(jsonDoubleRight);
+        }
+
+        @Test
+        void mailboxACLUpdatedShouldBeWellDeSerializedWithNullUser() {
+            assertThat(EVENT_SERIALIZER.fromJson(jsonDoubleRight).get())
+                .isEqualTo(mailboxACLUpdated);
+        }
+    }
+
+    @Nested
+    class DeserializationErrors {
+
+        @Nested
+        class DeserializationErrorOnSessionId {
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenMissingSessionId() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenNullSessionId() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":null," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenStringSessionId() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":\"123\"," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+        }
+
+        @Nested
+        class DeserializationErrorOnUser {
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenMissingUser() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":6" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenUserIsNotAString() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":12345" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenUserIsNotWellFormatted() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user@domain@secondDomain\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(IllegalArgumentException.class);
+            }
+        }
+
+        @Nested
+        class DeserializationErrorOnACLDiff {
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenMissingACLDiff() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+        }
+
+        @Nested
+        class DeserializationErrorOnOldACL {
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenMissingOldACLinACLDiff() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Nested
+            class DeserializationErrorOnOldACLEntryKey {
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNotIncludedNameInEntryKey() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{\"$\":\"ar\"}}," +
+                        "       \"newACL\":{}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(IllegalStateException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNameInEntryKeyIsNotString() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{1234:\"ar\"}}," +
+                        "       \"newACL\":{}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(JsonParseException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNameInEntryKeyIsEmpty() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{\"\":\"ar\"}}," +
+                        "       \"newACL\":{}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(IllegalArgumentException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNullEntryKey() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{null:\"ar\"}}," +
+                        "       \"newACL\":{}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(JsonParseException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenEntryKeyIsNotWellFormatted() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{\"-\":\"ar\"}}," +
+                        "       \"newACL\":{}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(StringIndexOutOfBoundsException.class);
+                }
+            }
+
+            @Nested
+            class DeserializationErrorOnOldACLRight {
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenUnsupportedRightInMailboxACL() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{\"$any\":\"unsupported\"}," +
+                        "       \"newACL\":{\"$any\":\"a\"}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(UnsupportedRightException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNullRightInMailboxACL() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{\"$any\":null}}," +
+                        "       \"newACL\":{}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenRightIsNotStringInMailboxACL() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{\"$any\":1234}}," +
+                        "       \"newACL\":{}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+
+            }
+        }
+
+        @Nested
+        class DeserializationErrorOnNewACL {
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenMissingNewACLinACLDiff() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Nested
+            class DeserializationErrorOnNewACLEntryKey {
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNotIncludedNameInEntryKey() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$\":\"ar\"}}," +
+                    "    \"mailboxId\":\"23\"," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                        .isInstanceOf(IllegalStateException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNameInEntryKeyIsNotString() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{1234:\"ar\"}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(JsonParseException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNameInEntryKeyIsEmpty() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"\":\"ar\"}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(IllegalArgumentException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNullEntryKey() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{null:\"ar\"}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(JsonParseException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenEntryKeyIsNotWellFormatted() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"-\":\"ar\"}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(StringIndexOutOfBoundsException.class);
+                }
+            }
+
+            @Nested
+            class DeserializationErrorOnNewACLRight {
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenUnsupportedRightInNewACL() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{\"$any\":\"a\"}," +
+                        "       \"newACL\":{\"$any\":\"unsupported\"}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(UnsupportedRightException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNullRightInMailboxACL() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"$any\":null}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenRightIsNotString() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":\"#private\"," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"$any\":1234}}," +
+                        "    \"mailboxId\":\"23\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+            }
+        }
+    }
+
+        @Nested
+        class DeserializationErrorOnMailboxId {
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenMissingMailboxId() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenNullMailboxId() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":null," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+
+            @Test
+            void mailboxACLUpdatedShouldThrowWhenMailboxIdIsANumber() {
+                assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                    "{" +
+                    "  \"MailboxACLUpdated\":{" +
+                    "    \"mailboxPath\":{" +
+                    "       \"namespace\":\"#private\"," +
+                    "       \"user\":\"bob\"," +
+                    "       \"name\":\"mailboxName\"" +
+                    "      }," +
+                    "    \"aclDiff\":{" +
+                    "       \"oldACL\":{}," +
+                    "       \"newACL\":{\"$any\":\"ar\"}}," +
+                    "    \"mailboxId\":123," +
+                    "    \"sessionId\":6," +
+                    "    \"user\":\"user\"" +
+                    "   }" +
+                    "}").get())
+                    .isInstanceOf(NoSuchElementException.class);
+            }
+        }
+
+        @Nested
+        class DeserializationErrorOnMailboxPath {
+
+            @Nested
+            class DeserializationErrorOnNameSpace {
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNameSpaceIsNotAString() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":230192.06," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"$any\":\"ar\"}}," +
+                        "    \"mailboxId\":\"123\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+            }
+
+            @Nested
+            class DeserializationErrorOnUser {
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenUserIsNotAString() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":230192.06," +
+                        "       \"user\":180806," +
+                        "       \"name\":\"mailboxName\"" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"$any\":\"ar\"}}," +
+                        "    \"mailboxId\":\"123\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+            }
+
+            @Nested
+            class DeserializationErrorOnMailboxName {
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenNullMailboxName() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":230192.06," +
+                        "       \"user\":180806," +
+                        "       \"name\":null" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"$any\":\"ar\"}}," +
+                        "    \"mailboxId\":\"123\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+
+                @Test
+                void mailboxACLUpdatedShouldThrowWhenMailboxNameIdIsANumber() {
+                    assertThatThrownBy(() -> EVENT_SERIALIZER.fromJson(
+                        "{" +
+                        "  \"MailboxACLUpdated\":{" +
+                        "    \"mailboxPath\":{" +
+                        "       \"namespace\":230192.06," +
+                        "       \"user\":\"bob\"," +
+                        "       \"name\":160205" +
+                        "      }," +
+                        "    \"aclDiff\":{" +
+                        "       \"oldACL\":{}," +
+                        "       \"newACL\":{\"$any\":\"ar\"}}," +
+                        "    \"mailboxId\":\"123\"," +
+                        "    \"sessionId\":6," +
+                        "    \"user\":\"user\"" +
+                        "   }" +
+                        "}").get())
+                        .isInstanceOf(NoSuchElementException.class);
+                }
+            }
+        }
+
+}


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