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 2021/01/27 02:43:02 UTC

[james-project] 01/02: JAMES-3490 Allow custom capability and method

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 4f20d11480aa2a2156b688618a3c96a10738cec5
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Mon Jan 25 16:15:06 2021 +0700

    JAMES-3490 Allow custom capability and method
---
 .../org/apache/james/jmap/draft/JMAPModule.java    |  11 ++
 .../rfc8621/contract/CustomMethodContract.scala    | 219 +++++++++++++++++++++
 .../rfc8621/memory/MemoryCustomMethodTest.java     |  39 ++++
 .../org/apache/james/jmap/core/Capabilities.scala  |  12 +-
 .../org/apache/james/jmap/core/Capability.scala    |   4 +-
 .../apache/james/jmap/routes/JMAPApiRoutes.scala   |  11 +-
 .../apache/james/jmap/routes/SessionSupplier.scala |   3 +-
 .../james/jmap/routes/JMAPApiRoutesTest.scala      |   6 +-
 8 files changed, 287 insertions(+), 18 deletions(-)

diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
index 95f6f5b..7a42557 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/draft/JMAPModule.java
@@ -35,6 +35,9 @@ import org.apache.james.jmap.JMAPConfiguration;
 import org.apache.james.jmap.JMAPServer;
 import org.apache.james.jmap.Version;
 import org.apache.james.jmap.change.MailboxChangeListener;
+import org.apache.james.jmap.core.Capability;
+import org.apache.james.jmap.core.DefaultCapabilities;
+import org.apache.james.jmap.core.JmapRfc8621Configuration;
 import org.apache.james.jmap.draft.methods.RequestHandler;
 import org.apache.james.jmap.draft.send.PostDequeueDecoratorFactory;
 import org.apache.james.jmap.draft.utils.JsoupHtmlTextExtractor;
@@ -131,6 +134,14 @@ public class JMAPModule extends AbstractModule {
         Multibinder<Version> supportedVersions = Multibinder.newSetBinder(binder(), Version.class);
         supportedVersions.addBinding().toInstance(Version.DRAFT);
         supportedVersions.addBinding().toInstance(Version.RFC8621);
+
+        Multibinder<Capability> supportedCapabilities = Multibinder.newSetBinder(binder(), Capability.class);
+        supportedCapabilities.addBinding().toInstance(DefaultCapabilities.coreCapability(JmapRfc8621Configuration.UPLOAD_LIMIT_30_MB()));
+        supportedCapabilities.addBinding().toInstance(DefaultCapabilities.MAIL_CAPABILITY());
+        supportedCapabilities.addBinding().toInstance(DefaultCapabilities.QUOTA_CAPABILITY());
+        supportedCapabilities.addBinding().toInstance(DefaultCapabilities.SHARES_CAPABILITY());
+        supportedCapabilities.addBinding().toInstance(DefaultCapabilities.VACATION_RESPONSE_CAPABILITY());
+        supportedCapabilities.addBinding().toInstance(DefaultCapabilities.SUBMISSION_CAPABILITY());
     }
 
     @Provides
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/CustomMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/CustomMethodContract.scala
new file mode 100644
index 0000000..87ca8d1
--- /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/CustomMethodContract.scala
@@ -0,0 +1,219 @@
+/****************************************************************
+ * 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 com.google.inject.AbstractModule
+import com.google.inject.multibindings.{Multibinder, ProvidesIntoSet}
+import eu.timepit.refined.auto._
+import io.netty.handler.codec.http.HttpHeaderNames.ACCEPT
+import io.restassured.RestAssured._
+import io.restassured.http.ContentType.JSON
+import net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson
+import org.apache.http.HttpStatus.SC_OK
+import org.apache.james.GuiceJamesServer
+import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE}
+import org.apache.james.jmap.core.Invocation.MethodName
+import org.apache.james.jmap.core.ResponseObject.SESSION_STATE
+import org.apache.james.jmap.core.{Capability, CapabilityProperties}
+import org.apache.james.jmap.http.UserCredential
+import org.apache.james.jmap.method.{InvocationWithContext, Method}
+import org.apache.james.jmap.rfc8621.contract.CustomMethodContract.CUSTOM
+import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder}
+import org.apache.james.mailbox.MailboxSession
+import org.apache.james.utils.DataProbeImpl
+import org.junit.jupiter.api.{BeforeEach, Test}
+import org.reactivestreams.Publisher
+import reactor.core.scala.publisher.SMono
+
+object CustomMethodContract {
+  val CUSTOM: CapabilityIdentifier = "urn:apache:james:params:jmap:custom"
+}
+
+case class CustomCapabilityProperties() extends CapabilityProperties
+
+case class CustomCapability(properties: CustomCapabilityProperties = CustomCapabilityProperties(), identifier: CapabilityIdentifier = CUSTOM) extends Capability
+
+class CustomCapabilitiesModule extends AbstractModule {
+  @ProvidesIntoSet
+  private def capability(): Capability = CustomCapability()
+}
+
+class CustomMethodModule extends AbstractModule {
+  override protected def configure(): Unit = {
+    install(new CustomCapabilitiesModule)
+    Multibinder.newSetBinder(binder(), classOf[Method])
+      .addBinding()
+      .to(classOf[CustomMethod])
+  }
+}
+
+class CustomMethod extends Method {
+
+  override val methodName = MethodName("Custom/echo")
+
+  override def process(capabilities: Set[CapabilityIdentifier], invocation: InvocationWithContext, mailboxSession: MailboxSession): Publisher[InvocationWithContext] = SMono.just(invocation)
+
+  override val requiredCapabilities: Set[CapabilityIdentifier] = Set(JMAP_CORE, CUSTOM)
+}
+
+trait CustomMethodContract {
+
+  @BeforeEach
+  def setUp(server: GuiceJamesServer): Unit = {
+    server.getProbe(classOf[DataProbeImpl])
+      .fluent()
+      .addDomain(DOMAIN.asString())
+      .addUser(BOB.asString(), BOB_PASSWORD)
+
+    requestSpecification = baseRequestSpecBuilder(server)
+      .setAuth(authScheme(UserCredential(BOB, BOB_PASSWORD)))
+      .build
+  }
+
+  @Test
+  def customMethodShouldRespondOKWithRFC8621VersionAndSupportedMethod(): Unit = {
+    val response = `given`()
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(
+        """{
+          |  "using": [
+          |    "urn:ietf:params:jmap:core", "urn:apache:james:params:jmap:custom"
+          |  ],
+          |  "methodCalls": [
+          |    [
+          |      "Custom/echo",
+          |      {
+          |        "arg1": "arg1data",
+          |        "arg2": "arg2data"
+          |      },
+          |      "c1"
+          |    ]
+          |  ]
+          |}""".stripMargin)
+    .when()
+      .post()
+    .`then`
+      .statusCode(SC_OK)
+      .contentType(JSON)
+      .extract()
+      .body()
+      .asString()
+
+    assertThatJson(response)
+      .isEqualTo(
+        s"""{
+          |  "sessionState": "${SESSION_STATE.value}",
+          |  "methodResponses": [
+          |    [
+          |      "Custom/echo",
+          |      {
+          |        "arg1": "arg1data",
+          |        "arg2": "arg2data"
+          |      },
+          |      "c1"
+          |    ]
+          |  ]
+          |}""".stripMargin)
+  }
+
+  @Test
+  def customMethodShouldReturnUnknownMethodWhenMissingCoreCapability(): Unit = {
+    val response = `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(
+        """{
+          |  "using": [
+          |    "urn:apache:james:params:jmap:custom"
+          |  ],
+          |  "methodCalls": [
+          |    [
+          |      "Custom/echo",
+          |      {
+          |        "arg1": "arg1data",
+          |        "arg2": "arg2data"
+          |      },
+          |      "c1"
+          |    ]
+          |  ]
+          |}""".stripMargin)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .contentType(JSON)
+      .extract
+      .body
+      .asString
+
+    assertThatJson(response).isEqualTo(
+      s"""{
+         |  "sessionState": "${SESSION_STATE.value}",
+         |  "methodResponses": [[
+         |    "error",
+         |    {
+         |      "type": "unknownMethod",
+         |      "description": "Missing capability(ies): urn:ietf:params:jmap:core"
+         |    },
+         |    "c1"]]
+         |}""".stripMargin)
+  }
+
+  @Test
+  def customMethodShouldReturnUnknownMethodWhenMissingCustomCapability(): Unit = {
+    val response = `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(
+        """{
+          |  "using": [
+          |    "urn:ietf:params:jmap:core"
+          |  ],
+          |  "methodCalls": [
+          |    [
+          |      "Custom/echo",
+          |      {
+          |        "arg1": "arg1data",
+          |        "arg2": "arg2data"
+          |      },
+          |      "c1"
+          |    ]
+          |  ]
+          |}""".stripMargin)
+    .when
+      .post
+    .`then`
+      .statusCode(SC_OK)
+      .contentType(JSON)
+      .extract
+      .body
+      .asString
+
+    assertThatJson(response).isEqualTo(
+      s"""{
+         |  "sessionState": "${SESSION_STATE.value}",
+         |  "methodResponses": [[
+         |    "error",
+         |    {
+         |      "type": "unknownMethod",
+         |      "description": "Missing capability(ies): urn:apache:james:params:jmap:custom"
+         |    },
+         |    "c1"]]
+         |}""".stripMargin)
+  }
+}
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/MemoryCustomMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryCustomMethodTest.java
new file mode 100644
index 0000000..2b2c8d1
--- /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/MemoryCustomMethodTest.java
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.CustomMethodContract;
+import org.apache.james.jmap.rfc8621.contract.CustomMethodModule;
+import org.apache.james.modules.TestJMAPServerModule;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class MemoryCustomMethodTest implements CustomMethodContract {
+    @RegisterExtension
+    static JamesServerExtension testExtension = new JamesServerBuilder<>(JamesServerBuilder.defaultConfigurationProvider())
+        .server(configuration -> GuiceJamesServer.forConfiguration(configuration)
+            .combineWith(IN_MEMORY_SERVER_AGGREGATE_MODULE, new CustomMethodModule())
+            .overrideWith(new TestJMAPServerModule()))
+        .build();
+}
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala
index 40fd95d..af4ad66 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capabilities.scala
@@ -22,7 +22,7 @@ import eu.timepit.refined.auto._
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, EMAIL_SUBMISSION, JAMES_QUOTA, JAMES_SHARES, JMAP_CORE, JMAP_MAIL, JMAP_VACATION_RESPONSE}
 
 object DefaultCapabilities {
-  private def coreCapability(maxUploadSize: MaxSizeUpload) = CoreCapability(
+  def coreCapability(maxUploadSize: MaxSizeUpload) = CoreCapability(
     properties = CoreCapabilityProperties(
       maxUploadSize,
       MaxConcurrentUpload(4L),
@@ -32,7 +32,7 @@ object DefaultCapabilities {
       MaxObjectsInGet(500L),
       MaxObjectsInSet(500L),
       collationAlgorithms = List("i;unicode-casemap")))
-  private val MAIL_CAPABILITY = MailCapability(
+  val MAIL_CAPABILITY = MailCapability(
     properties = MailCapabilityProperties(
       MaxMailboxesPerEmail(Some(10_000_000L)),
       MaxMailboxDepth(None),
@@ -40,10 +40,10 @@ object DefaultCapabilities {
       MaxSizeAttachmentsPerEmail(20_000_000L),
       emailQuerySortOptions = List("receivedAt", "sentAt"),
       MayCreateTopLevelMailbox(true)))
-  private val QUOTA_CAPABILITY = QuotaCapability()
-  private val SHARES_CAPABILITY = SharesCapability()
-  private val VACATION_RESPONSE_CAPABILITY = VacationResponseCapability()
-  private val SUBMISSION_CAPABILITY = SubmissionCapability()
+  val QUOTA_CAPABILITY = QuotaCapability()
+  val SHARES_CAPABILITY = SharesCapability()
+  val VACATION_RESPONSE_CAPABILITY = VacationResponseCapability()
+  val SUBMISSION_CAPABILITY = SubmissionCapability()
 
   val SUPPORTED_CAPABILITY_IDENTIFIERS: Set[CapabilityIdentifier] =
     Set(JMAP_CORE, JMAP_MAIL, JMAP_VACATION_RESPONSE, JAMES_SHARES, JAMES_QUOTA, EMAIL_SUBMISSION)
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capability.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capability.scala
index 072dc24..94b0c50 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capability.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/core/Capability.scala
@@ -45,7 +45,7 @@ object CapabilityIdentifier {
   val JAMES_SHARES: CapabilityIdentifier = "urn:apache:james:params:jmap:mail:shares"
 }
 
-sealed trait CapabilityProperties
+trait CapabilityProperties
 
 trait Capability {
   def identifier(): CapabilityIdentifier
@@ -126,4 +126,4 @@ final case class SharesCapability(properties: SharesCapabilityProperties = Share
 final case class VacationResponseCapabilityProperties() extends CapabilityProperties
 
 final case class VacationResponseCapability(properties: VacationResponseCapabilityProperties = VacationResponseCapabilityProperties(),
-                                            identifier: CapabilityIdentifier = JMAP_VACATION_RESPONSE) extends Capability
+                                            identifier: CapabilityIdentifier = JMAP_VACATION_RESPONSE) extends Capability
\ No newline at end of file
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala
index fb27d2e..faf7742 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/JMAPApiRoutes.scala
@@ -33,7 +33,7 @@ import org.apache.james.jmap.JMAPUrls.JMAP
 import org.apache.james.jmap.core.CapabilityIdentifier.CapabilityIdentifier
 import org.apache.james.jmap.core.Invocation.MethodName
 import org.apache.james.jmap.core.ProblemDetails.{notJSONProblem, notRequestProblem, unknownCapabilityProblem}
-import org.apache.james.jmap.core.{DefaultCapabilities, ErrorCode, Invocation, MissingCapabilityException, ProblemDetails, RequestObject, ResponseObject}
+import org.apache.james.jmap.core.{Capability, ErrorCode, Invocation, MissingCapabilityException, ProblemDetails, RequestObject, ResponseObject}
 import org.apache.james.jmap.exceptions.UnauthorizedException
 import org.apache.james.jmap.http.rfc8621.InjectionKeys
 import org.apache.james.jmap.http.{Authenticator, UserProvisioning}
@@ -57,15 +57,16 @@ object JMAPApiRoutes {
 
 class JMAPApiRoutes (val authenticator: Authenticator,
                      userProvisioner: UserProvisioning,
-                     methods: Set[Method]) extends JMAPRoutes {
+                     methods: Set[Method],
+                     defaultCapabilities: Set[Capability]) extends JMAPRoutes {
 
   private val methodsByName: Map[MethodName, Method] = methods.map(method => method.methodName -> method).toMap
 
   @Inject
   def this(@Named(InjectionKeys.RFC_8621) authenticator: Authenticator,
            userProvisioner: UserProvisioning,
-           javaMethods: java.util.Set[Method]) {
-    this(authenticator, userProvisioner, javaMethods.asScala.toSet)
+           javaMethods: java.util.Set[Method], supportedCapabilities: java.util.Set[Capability]) {
+    this(authenticator, userProvisioner, javaMethods.asScala.toSet, supportedCapabilities.asScala.toSet)
   }
 
   override def routes(): stream.Stream[JMAPRoute] = Stream.of(
@@ -109,7 +110,7 @@ class JMAPApiRoutes (val authenticator: Authenticator,
                       httpServerResponse: HttpServerResponse,
                       mailboxSession: MailboxSession): SMono[Void] = {
     val processingContext: ProcessingContext = ProcessingContext(Map.empty, Map.empty)
-    val unsupportedCapabilities = requestObject.using.toSet -- DefaultCapabilities.SUPPORTED_CAPABILITY_IDENTIFIERS
+    val unsupportedCapabilities = requestObject.using.toSet -- defaultCapabilities.map(_.identifier())
     val capabilities: Set[CapabilityIdentifier] = requestObject.using.toSet
 
     if (unsupportedCapabilities.nonEmpty) {
diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala
index c2af050..c9d631c 100644
--- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala
+++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/routes/SessionSupplier.scala
@@ -23,9 +23,8 @@ import javax.inject.Inject
 import org.apache.james.core.Username
 import org.apache.james.jmap.core.CapabilityIdentifier.CapabilityIdentifier
 import org.apache.james.jmap.core.{Account, AccountId, DefaultCapabilities, IsPersonal, IsReadOnly, JmapRfc8621Configuration, Session}
-import reactor.core.scala.publisher.SMono
 
-class SessionSupplier @Inject() (val configuration: JmapRfc8621Configuration){
+class SessionSupplier @Inject() (val configuration: JmapRfc8621Configuration) {
   private val maxSizeUpload = configuration.maxUploadSize
 
   def generate(username: Username): Either[IllegalArgumentException, Session] =
diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala
index 1ea3a45..fece846 100644
--- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala
+++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/routes/JMAPApiRoutesTest.scala
@@ -38,8 +38,8 @@ import org.apache.james.domainlist.memory.MemoryDomainList
 import org.apache.james.jmap.JMAPUrls.JMAP
 import org.apache.james.jmap.core.CapabilityIdentifier.{CapabilityIdentifier, JMAP_CORE}
 import org.apache.james.jmap.core.Invocation.MethodName
-import org.apache.james.jmap.core.RequestLevelErrorType
 import org.apache.james.jmap.core.ResponseObject.SESSION_STATE
+import org.apache.james.jmap.core.{DefaultCapabilities, JmapRfc8621Configuration, RequestLevelErrorType}
 import org.apache.james.jmap.http.{Authenticator, BasicAuthenticationStrategy, UserProvisioning}
 import org.apache.james.jmap.method.{CoreEchoMethod, Method}
 import org.apache.james.jmap.routes.JMAPApiRoutesTest._
@@ -78,7 +78,7 @@ object JMAPApiRoutesTest {
   private val userProvisionner: UserProvisioning = new UserProvisioning(usersRepository, new RecordingMetricFactory)
   private val JMAP_METHODS: Set[Method] = Set(new CoreEchoMethod)
 
-  private val JMAP_API_ROUTE: JMAPApiRoutes = new JMAPApiRoutes(AUTHENTICATOR, userProvisionner, JMAP_METHODS)
+  private val JMAP_API_ROUTE: JMAPApiRoutes = new JMAPApiRoutes(AUTHENTICATOR, userProvisionner, JMAP_METHODS, DefaultCapabilities.supported(JmapRfc8621Configuration.UPLOAD_LIMIT_30_MB).capabilities.toSet)
   private val ROUTES_HANDLER: ImmutableSet[JMAPRoutesHandler] = ImmutableSet.of(new JMAPRoutesHandler(Version.RFC8621, JMAP_API_ROUTE))
 
   private val userBase64String: String = Base64.getEncoder.encodeToString("user1:password".getBytes(StandardCharsets.UTF_8))
@@ -442,7 +442,7 @@ class JMAPApiRoutesTest extends AnyFlatSpec with BeforeAndAfter with Matchers {
     when(mockCoreEchoMethod.requiredCapabilities).thenReturn(Set(JMAP_CORE))
 
     val methods: Set[Method] = Set(mockCoreEchoMethod)
-    val apiRoute: JMAPApiRoutes = new JMAPApiRoutes(AUTHENTICATOR, userProvisionner, methods)
+    val apiRoute: JMAPApiRoutes = new JMAPApiRoutes(AUTHENTICATOR, userProvisionner, methods, DefaultCapabilities.supported(JmapRfc8621Configuration.UPLOAD_LIMIT_30_MB).capabilities.toSet)
     val routesHandler: ImmutableSet[JMAPRoutesHandler] = ImmutableSet.of(new JMAPRoutesHandler(Version.RFC8621, apiRoute))
 
     val versionParser: VersionParser = new VersionParser(SUPPORTED_VERSIONS, JMAPConfiguration.DEFAULT)


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