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 rc...@apache.org on 2020/06/08 03:12:34 UTC

[james-project] 13/16: JAMES-3171 Mailbox/get all integration tests

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

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

commit ac9890279c3b7434703110982f71461241d0a08d
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Fri May 22 21:59:56 2020 +0700

    JAMES-3171 Mailbox/get all integration tests
---
 .../DistributedMailboxGetMethodTest.java           |  51 +++
 .../james/jmap/rfc8621/contract/Fixture.scala      |   2 +
 .../contract/MailboxGetMethodContract.scala        | 476 +++++++++++++++++++++
 .../rfc8621/memory/MemoryMailboxGetMethodTest.java |  38 ++
 4 files changed, 567 insertions(+)

diff --git a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
new file mode 100644
index 0000000..d2db630
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedMailboxGetMethodTest.java
@@ -0,0 +1,51 @@
+/****************************************************************
+ * 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.rfc8621.distributed;
+
+import org.apache.james.CassandraExtension;
+import org.apache.james.CassandraRabbitMQJamesConfiguration;
+import org.apache.james.CassandraRabbitMQJamesServerMain;
+import org.apache.james.DockerElasticSearchExtension;
+import org.apache.james.JamesServerBuilder;
+import org.apache.james.JamesServerExtension;
+import org.apache.james.jmap.rfc8621.contract.MailboxGetMethodContract;
+import org.apache.james.modules.AwsS3BlobStoreExtension;
+import org.apache.james.modules.RabbitMQExtension;
+import org.apache.james.modules.TestJMAPServerModule;
+import org.apache.james.modules.blobstore.BlobStoreConfiguration;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class DistributedMailboxGetMethodTest implements MailboxGetMethodContract {
+    @RegisterExtension
+    static JamesServerExtension testExtension = new JamesServerBuilder<CassandraRabbitMQJamesConfiguration>(tmpDir ->
+        CassandraRabbitMQJamesConfiguration.builder()
+            .workingDirectory(tmpDir)
+            .configurationFromClasspath()
+            .blobStore(BlobStoreConfiguration.objectStorage().disableCache())
+            .build())
+        .extension(new DockerElasticSearchExtension())
+        .extension(new CassandraExtension())
+        .extension(new RabbitMQExtension())
+        .extension(new AwsS3BlobStoreExtension())
+        .server(configuration -> CassandraRabbitMQJamesServerMain.createServer(configuration)
+            .overrideWith(new TestJMAPServerModule()))
+        .build();
+
+}
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/Fixture.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/Fixture.scala
index 7d22579..799f8f9 100644
--- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/Fixture.scala
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/Fixture.scala
@@ -69,8 +69,10 @@ object Fixture {
   val DOMAIN_WITH_SPACE: Domain = Domain.of("dom ain.tld")
   val _2_DOT_DOMAIN: Domain = Domain.of("do.main.tld")
   val BOB: Username = Username.fromLocalPartWithDomain("bob", DOMAIN)
+  val ANDRE: Username = Username.fromLocalPartWithDomain("andre", DOMAIN)
   val ALICE: Username = Username.fromLocalPartWithDomain("alice", _2_DOT_DOMAIN)
   val BOB_PASSWORD: String = "bobpassword"
+  val ANDRE_PASSWORD: String = "andrepassword"
   val ALICE_PASSWORD: String = "alicepassword"
 
   val BOB_BASIC_AUTH_HEADER: Header = new Header(AUTHORIZATION_HEADER, s"Basic ${toBase64(s"${BOB.asString}:$BOB_PASSWORD")}")
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/MailboxGetMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxGetMethodContract.scala
new file mode 100644
index 0000000..0748914
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxGetMethodContract.scala
@@ -0,0 +1,476 @@
+/****************************************************************
+ * 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.rfc8621.contract
+
+import java.io.ByteArrayInputStream
+import java.nio.charset.StandardCharsets
+import java.util.Date
+
+import io.netty.handler.codec.http.HttpHeaderNames.ACCEPT
+import io.restassured.RestAssured._
+import io.restassured.http.ContentType.JSON
+import javax.mail.Flags
+import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson
+import org.apache.http.HttpStatus.{SC_INTERNAL_SERVER_ERROR, SC_OK}
+import org.apache.james.GuiceJamesServer
+import org.apache.james.core.quota.{QuotaCountLimit, QuotaSizeLimit}
+import org.apache.james.jmap.http.UserCredential
+import org.apache.james.jmap.rfc8621.contract.Fixture._
+import org.apache.james.jmap.rfc8621.contract.tags.CategoryTags
+import org.apache.james.mailbox.MessageManager.AppendCommand
+import org.apache.james.mailbox.model.MailboxACL.Right
+import org.apache.james.mailbox.model.{MailboxACL, MailboxId, MailboxPath}
+import org.apache.james.mailbox.{DefaultMailboxes, Role}
+import org.apache.james.mime4j.dom.Message
+import org.apache.james.modules.{ACLProbeImpl, MailboxProbeImpl, QuotaProbesImpl}
+import org.apache.james.utils.DataProbeImpl
+import org.hamcrest.Matchers._
+import org.junit.jupiter.api.{BeforeEach, Tag, Test}
+
+object MailboxGetMethodContract {
+  private val ARGUMENTS: String = "methodResponses[0][1]"
+  private val FIRST_MAILBOX: String = ARGUMENTS + ".list[0]"
+  private val SECOND_MAILBOX: String = ARGUMENTS + ".list[1]"
+
+  private val LOOKUP: String = Right.Lookup.asCharacter.toString
+  private val READ: String = Right.Read.asCharacter.toString
+  private val ADMINISTER: String = Right.Administer.asCharacter.toString
+
+  private val GET_ALL_MAILBOXES_REQUEST: String =
+    """{
+    |  "using": [
+    |    "urn:ietf:params:jmap:core",
+    |    "urn:ietf:params:jmap:mail"],
+    |  "methodCalls": [[
+    |      "Mailbox/get",
+    |      {
+    |        "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+    |        "ids": null
+    |      },
+    |      "c1"]]
+    |}""".stripMargin
+}
+
+trait MailboxGetMethodContract {
+  import MailboxGetMethodContract._
+
+  @BeforeEach
+  def setUp(server: GuiceJamesServer): Unit = {
+    server.getProbe(classOf[DataProbeImpl])
+      .fluent
+      .addDomain(DOMAIN.asString)
+      .addUser(BOB.asString, BOB_PASSWORD)
+      .addUser(ANDRE.asString, ANDRE_PASSWORD)
+
+    requestSpecification = baseRequestSpecBuilder(server)
+      .setAuth(authScheme(UserCredential(BOB, BOB_PASSWORD)))
+      .build
+  }
+
+  @Test
+  def getMailboxesShouldReturnExistingMailbox(server: GuiceJamesServer): Unit = {
+    val mailboxId: String = server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, "custom"))
+      .serialize
+
+    val response: String = `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .contentType(JSON)
+      .extract
+      .body
+      .asString
+
+    assertThatJson(response).isEqualTo(
+      s"""{
+         |  "sessionState": "75128aab4b1b",
+         |  "methodResponses": [[
+         |    "Mailbox/get",
+         |    {
+         |      "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+         |      "state": "000001",
+         |      "list": [
+         |        {
+         |          "id": "${mailboxId}",
+         |          "name": "custom",
+         |          "sortOrder": 1000,
+         |          "totalEmails": 0,
+         |          "unreadEmails": 0,
+         |          "totalThreads": 0,
+         |          "unreadThreads": 0,
+         |          "myRights": {
+         |            "mayReadItems": true,
+         |            "mayAddItems": true,
+         |            "mayRemoveItems": true,
+         |            "maySetSeen": true,
+         |            "maySetKeywords": true,
+         |            "mayCreateChild": true,
+         |            "mayRename": true,
+         |            "mayDelete": true,
+         |            "maySubmit": true
+         |          },
+         |          "isSubscribed": false,
+         |          "namespace": "Personal",
+         |          "rights": {},
+         |          "quotas": {
+         |            "#private&bob@domain.tld": {
+         |              "Storage": { "used": 0},
+         |              "Message": {"used": 0}
+         |            }
+         |          }
+         |        }
+         |      ],
+         |      "notFound": []
+         |    },
+         |    "c1"]]
+         |}""".stripMargin)
+  }
+
+  @Test
+  @Tag(CategoryTags.BASIC_FEATURE)
+  def getMailboxesShouldReturnEmptyWhenNone(): Unit = {
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", empty)
+  }
+
+  @Test
+  @Tag(CategoryTags.BASIC_FEATURE)
+  def getMailboxesShouldReturnAllExistingMailboxes(server: GuiceJamesServer): Unit = {
+    val firstMailboxName: String = "custom"
+    val mailboxId1: String = server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, firstMailboxName))
+      .serialize
+
+    val secondMailboxName: String = "othercustom"
+    val mailboxId2: String = server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, secondMailboxName))
+      .serialize
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(2))
+      .body(s"$FIRST_MAILBOX.id", equalTo(mailboxId1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(firstMailboxName))
+      .body(s"$SECOND_MAILBOX.id", equalTo(mailboxId2))
+      .body(s"$SECOND_MAILBOX.name", equalTo(secondMailboxName))
+  }
+
+  @Test
+  def getMailboxesShouldReturnOnlyMailboxesOfCurrentUser(server: GuiceJamesServer): Unit = {
+    val mailboxName: String = "custom"
+    val mailboxId: String = server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, "custom"))
+      .serialize
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(ANDRE, "andrecustom"))
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.id", equalTo(mailboxId))
+      .body(s"$FIRST_MAILBOX.name", equalTo(mailboxName))
+  }
+
+  @Test
+  def getMailboxesShouldReturnSharedRights(server: GuiceJamesServer): Unit = {
+    val targetUser1: String = "touser1@" + DOMAIN.asString
+    val targetUser2: String = "touser2@" + DOMAIN.asString
+    val mailboxName: String = "myMailbox"
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, mailboxName))
+      .serialize
+
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(MailboxPath.forUser(BOB, mailboxName), targetUser1, new MailboxACL.Rfc4314Rights(Right.Lookup, Right.Administer))
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(MailboxPath.forUser(BOB, mailboxName), targetUser2, new MailboxACL.Rfc4314Rights(Right.Read, Right.Lookup))
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(mailboxName))
+      .body(s"$FIRST_MAILBOX.rights['$targetUser1']", contains(ADMINISTER, LOOKUP))
+      .body(s"$FIRST_MAILBOX.rights['$targetUser2']", contains(LOOKUP, READ))
+  }
+
+  @Test
+  @Tag(CategoryTags.BASIC_FEATURE)
+  def getMailboxesShouldReturnDelegatedNamespaceWhenSharedMailbox(server: GuiceJamesServer): Unit = {
+    val sharedMailboxName = "AndreShared"
+    val andreMailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName)
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(andreMailboxPath)
+      .serialize
+
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(andreMailboxPath, BOB.asString, new MailboxACL.Rfc4314Rights(Right.Lookup))
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(sharedMailboxName))
+      .body(s"$FIRST_MAILBOX.namespace", equalTo(s"Delegated[${ANDRE.asString}]"))
+      .body(s"$FIRST_MAILBOX.rights['${BOB.asString}']", contains(LOOKUP))
+  }
+
+  @Test
+  @Tag(CategoryTags.BASIC_FEATURE)
+  def getMailboxesShouldNotReturnOtherPeopleRightsAsSharee(server: GuiceJamesServer): Unit = {
+    val toUser1: String = "touser1@" + DOMAIN.asString
+    val sharedMailboxName: String = "AndreShared"
+    val andreMailboxPath: MailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName)
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(andreMailboxPath)
+      .serialize
+
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(andreMailboxPath, BOB.asString, new MailboxACL.Rfc4314Rights(Right.Lookup, Right.Read))
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(andreMailboxPath, toUser1, new MailboxACL.Rfc4314Rights(Right.Lookup, Right.Read))
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(sharedMailboxName))
+      .body(s"$FIRST_MAILBOX.rights['${BOB.asString}']", contains(LOOKUP, READ))
+      .body(s"$FIRST_MAILBOX.rights['$toUser1']", nullValue)
+  }
+
+  @Test
+  def getMailboxesShouldReturnPartiallyAllowedMayPropertiesWhenDelegated(server: GuiceJamesServer): Unit = {
+    val toUser1: String = "touser1@" + DOMAIN.asString
+    val sharedMailboxName: String = "AndreShared"
+    val andreMailboxPath: MailboxPath = MailboxPath.forUser(ANDRE, sharedMailboxName)
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(andreMailboxPath)
+      .serialize
+
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(andreMailboxPath, BOB.asString, new MailboxACL.Rfc4314Rights(Right.Lookup, Right.Read))
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(andreMailboxPath, toUser1, new MailboxACL.Rfc4314Rights(Right.Lookup, Right.Read))
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(sharedMailboxName))
+      .body(s"$FIRST_MAILBOX.myRights.mayReadItems", equalTo(true))
+      .body(s"$FIRST_MAILBOX.myRights.mayAddItems", equalTo(false))
+      .body(s"$FIRST_MAILBOX.myRights.mayRemoveItems", equalTo(false))
+      .body(s"$FIRST_MAILBOX.myRights.mayCreateChild", equalTo(false))
+      .body(s"$FIRST_MAILBOX.myRights.mayDelete", equalTo(false))
+      .body(s"$FIRST_MAILBOX.myRights.mayRename", equalTo(false))
+      .body(s"$FIRST_MAILBOX.myRights.maySubmit", equalTo(false))
+      .body(s"$FIRST_MAILBOX.myRights.maySetSeen", equalTo(false))
+      .body(s"$FIRST_MAILBOX.myRights.maySetKeywords", equalTo(false))
+  }
+
+  @Test
+  @Tag(CategoryTags.BASIC_FEATURE)
+  def getMailboxesShouldNotReturnInboxRoleToShareeWhenDelegatedInbox(server: GuiceJamesServer): Unit = {
+    val andreMailboxPath = MailboxPath.forUser(ANDRE, DefaultMailboxes.INBOX)
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(andreMailboxPath)
+      .serialize
+
+    server.getProbe(classOf[ACLProbeImpl])
+      .replaceRights(andreMailboxPath, BOB.asString, new MailboxACL.Rfc4314Rights(Right.Lookup))
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(DefaultMailboxes.INBOX))
+      .body(s"$FIRST_MAILBOX.role", nullValue)
+      .body(s"$FIRST_MAILBOX.sortOrder", equalTo(1000))
+  }
+
+  @Test
+  def getMailboxesShouldReturnCorrectMailboxRole(server: GuiceJamesServer): Unit = {
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, DefaultMailboxes.INBOX))
+      .serialize
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(DefaultMailboxes.INBOX))
+      .body(s"$FIRST_MAILBOX.role", equalTo(Role.INBOX.serialize))
+      .body(s"$FIRST_MAILBOX.sortOrder", equalTo(10))
+  }
+
+  @Test
+  @Tag(CategoryTags.BASIC_FEATURE)
+  def getMailboxesShouldReturnUpdatedQuotasForInboxWhenMailReceived(server: GuiceJamesServer): Unit = {
+    val message: Message = Message.Builder
+      .of
+      .setSubject("test")
+      .setBody("testmail", StandardCharsets.UTF_8)
+      .build
+
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, DefaultMailboxes.INBOX))
+      .serialize
+
+    server.getProbe(classOf[MailboxProbeImpl])
+      .appendMessage(BOB.asString, MailboxPath.forUser(BOB, DefaultMailboxes.INBOX), AppendCommand.from(message))
+    server.getProbe(classOf[MailboxProbeImpl])
+      .appendMessage(BOB.asString, MailboxPath.forUser(BOB, DefaultMailboxes.INBOX),
+        new ByteArrayInputStream("Subject: test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags(Flags.Flag.SEEN))
+
+    Thread.sleep(1000) //dirty fix for distributed integration test...
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(DefaultMailboxes.INBOX))
+      .body(s"$FIRST_MAILBOX.quotas['#private&bob@domain.tld']['Storage'].used", equalTo(110))
+      .body(s"$FIRST_MAILBOX.quotas['#private&bob@domain.tld']['Storage'].max", nullValue)
+      .body(s"$FIRST_MAILBOX.quotas['#private&bob@domain.tld']['Message'].used", equalTo(2))
+      .body(s"$FIRST_MAILBOX.quotas['#private&bob@domain.tld']['Message'].max", nullValue)
+  }
+
+  @Test
+  def getMailboxesShouldReturnMaximumQuotasWhenSet(server: GuiceJamesServer): Unit = {
+    server.getProbe(classOf[QuotaProbesImpl])
+      .setGlobalMaxStorage(QuotaSizeLimit.size(142))
+    server.getProbe(classOf[QuotaProbesImpl])
+      .setGlobalMaxMessageCount(QuotaCountLimit.count(31))
+
+    server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, DefaultMailboxes.INBOX))
+      .serialize
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(1))
+      .body(s"$FIRST_MAILBOX.name", equalTo(DefaultMailboxes.INBOX))
+      .body(s"$FIRST_MAILBOX.quotas['#private&bob@domain.tld']['Storage'].max", equalTo(142))
+      .body(s"$FIRST_MAILBOX.quotas['#private&bob@domain.tld']['Message'].max", equalTo(31))
+  }
+
+  @Test
+  def getMailboxesShouldReturnMailboxesInSorteredOrder(server: GuiceJamesServer): Unit = {
+    val mailboxId1: String = server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, DefaultMailboxes.TRASH))
+      .serialize
+    val mailboxId2: String = server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, DefaultMailboxes.INBOX))
+      .serialize
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(GET_ALL_MAILBOXES_REQUEST)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .body(s"$ARGUMENTS.list", hasSize(2))
+      .body(s"$FIRST_MAILBOX.id", equalTo(mailboxId2))
+      .body(s"$FIRST_MAILBOX.name", equalTo(DefaultMailboxes.INBOX))
+      .body(s"$FIRST_MAILBOX.sortOrder", equalTo(10))
+      .body(s"$SECOND_MAILBOX.id", equalTo(mailboxId1))
+      .body(s"$SECOND_MAILBOX.name", equalTo(DefaultMailboxes.TRASH))
+      .body(s"$SECOND_MAILBOX.sortOrder", equalTo(60))
+  }
+
+  @Test
+  def getMailboxesByIdsShouldNotBeImplementedYet(server: GuiceJamesServer): Unit = {
+    val mailboxId: MailboxId = server.getProbe(classOf[MailboxProbeImpl])
+      .createMailbox(MailboxPath.forUser(BOB, "custom"))
+
+    `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(s"""{
+              |  "using": [
+              |    "urn:ietf:params:jmap:core",
+              |    "urn:ietf:params:jmap:mail"],
+              |  "methodCalls": [[
+              |      "Mailbox/get",
+              |      {
+              |        "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+              |        "ids": ["${mailboxId}"]
+              |      },
+              |      "c1"]]
+              |}""".stripMargin)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_INTERNAL_SERVER_ERROR)
+  }
+}
diff --git a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxGetMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxGetMethodTest.java
new file mode 100644
index 0000000..70db27f
--- /dev/null
+++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryMailboxGetMethodTest.java
@@ -0,0 +1,38 @@
+/****************************************************************
+ * 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.rfc8621.memory;
+
+import static org.apache.james.MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.JamesServerBuilder;
+import org.apache.james.JamesServerExtension;
+import org.apache.james.jmap.rfc8621.contract.MailboxGetMethodContract;
+import org.apache.james.modules.TestJMAPServerModule;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class MemoryMailboxGetMethodTest implements MailboxGetMethodContract {
+    @RegisterExtension
+    static JamesServerExtension testExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
+        .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
+            .combineWith(IN_MEMORY_SERVER_AGGREGATE_MODULE)
+            .overrideWith(new TestJMAPServerModule()))
+        .build();
+}


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