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 2b1d2e71090b9fc65ff72ad6c1c02bd711e412a7
Author: Benoit Tellier <btell...@linagora.com>
AuthorDate: Mon Aug 17 14:02:37 2020 +0700

    JAMES-3359 Mailbox/set update should accept creationIds
---
 .../contract/MailboxSetMethodContract.scala        | 89 +++++++++++++++++++++-
 .../org/apache/james/jmap/json/Serializer.scala    | 21 ++++-
 .../org/apache/james/jmap/mail/MailboxSet.scala    |  4 +-
 .../james/jmap/method/MailboxSetMethod.scala       | 13 ++--
 4 files changed, 116 insertions(+), 11 deletions(-)

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/MailboxSetMethodContract.scala
 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
index b1853b9..180a198 100644
--- 
a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
+++ 
b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/MailboxSetMethodContract.scala
@@ -2077,7 +2077,94 @@ trait MailboxSetMethodContract {
          |}""".stripMargin)
   }
 
-  // TODO update using creation ids
+  @Test
+  def updateShouldAcceptCreationIds(server: GuiceJamesServer): Unit = {
+    val request =
+      s"""
+        |{
+        |   "using": [ "urn:ietf:params:jmap:core", 
"urn:ietf:params:jmap:mail" ],
+        |   "methodCalls": [
+        |       ["Mailbox/set",
+        |           {
+        |                "accountId": 
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+        |                "create": {
+        |                    "C43": {
+        |                      "name": "mailbox"
+        |                    }
+        |                }
+        |           },
+        |    "c1"],
+        |      ["Mailbox/set",
+        |          {
+        |               "accountId": 
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+        |               "update": {
+        |                 "#C43" : {
+        |                   "/name": "newName"
+        |                 }
+        |               }
+        |          },
+        |     "c2"]
+        |   ]
+        |}
+        |""".stripMargin
+
+    val response = `given`
+      .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER)
+      .body(request)
+    .when
+      .post
+    .`then`
+      .log().ifValidationFails()
+      .statusCode(SC_OK)
+      .contentType(JSON)
+      .extract
+      .body
+      .asString
+
+    val mailboxId: String = server.getProbe(classOf[MailboxProbeImpl])
+      .getMailboxId("#private", BOB.asString(), "newName")
+      .serialize()
+
+    assertThatJson(response).isEqualTo(
+      s"""{
+         |     "sessionState": "75128aab4b1b",
+         |     "methodResponses": [
+         |             ["Mailbox/set", {
+         |                     "accountId": 
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+         |                     "newState": "000001",
+         |                     "created": {
+         |                             "C43": {
+         |                                     "id": "$mailboxId",
+         |                                     "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": true
+         |                             }
+         |                     }
+         |             }, "c1"],
+         |             ["Mailbox/set", {
+         |                     "accountId": 
"29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+         |                     "newState": "000001",
+         |                     "updated": {
+         |                             "$mailboxId": {}
+         |                     }
+         |             }, "c2"]
+         |     ]
+         |}""".stripMargin)
+  }
+
   // TODO invalid path handling (unknown property, invalid name)
   // TODO mailbox already exists, too long name
   // TODO disable destroy / rename of sustem mailbox
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
index b655527..a813bf3 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/json/Serializer.scala
@@ -241,9 +241,24 @@ class Serializer @Inject() (mailboxIdFactory: 
MailboxId.Factory) {
   implicit val mailboxCreationRequest: Reads[MailboxCreationRequest] = 
Json.reads[MailboxCreationRequest]
   private implicit val mailboxPatchObject: Reads[MailboxPatchObject] = 
Json.valueReads[MailboxPatchObject]
 
-  private implicit val mapPatchObjectByMailboxIdReads: Reads[Map[MailboxId, 
MailboxPatchObject]] = _.validate[Map[String, MailboxPatchObject]]
-    .map(mapWithStringKey => mapWithStringKey
-      .map(keyValue => (mailboxIdFactory.fromString(keyValue._1), 
keyValue._2)))
+  private implicit val mapPatchObjectByMailboxIdReads: 
Reads[Map[UnparsedMailboxId, MailboxPatchObject]] = _.validate[Map[String, 
MailboxPatchObject]]
+    .flatMap(mapWithStringKey =>{
+      mapWithStringKey
+        .foldLeft[Either[JsError, Map[UnparsedMailboxId, 
MailboxPatchObject]]](scala.util.Right[JsError, Map[UnparsedMailboxId, 
MailboxPatchObject]](Map.empty))((acc: Either[JsError, Map[UnparsedMailboxId, 
MailboxPatchObject]], keyValue) => {
+          acc match {
+            case error@Left(_) => error
+            case scala.util.Right(validatedAcc) =>
+              val refinedKey: Either[String, UnparsedMailboxId] = 
refineV(keyValue._1)
+              refinedKey match {
+                case Left(error) => Left(JsError(error))
+                case scala.util.Right(unparsedMailboxId) => 
scala.util.Right(validatedAcc + (unparsedMailboxId -> keyValue._2))
+              }
+          }
+        }) match {
+        case Left(jsError) => jsError
+        case scala.util.Right(value) => JsSuccess(value)
+      }
+    })
 
   private implicit val mapCreationRequestByMailBoxCreationId: 
Reads[Map[MailboxCreationId, JsObject]] = _.validate[Map[String, JsObject]]
     .flatMap(mapWithStringKey => {
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala
index 51821dd..3452209 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/mail/MailboxSet.scala
@@ -34,7 +34,7 @@ import play.api.libs.json.{JsObject, JsString, JsValue}
 case class MailboxSetRequest(accountId: AccountId,
                              ifInState: Option[State],
                              create: Option[Map[MailboxCreationId, JsObject]],
-                             update: Option[Map[MailboxId, 
MailboxPatchObject]],
+                             update: Option[Map[UnparsedMailboxId, 
MailboxPatchObject]],
                              destroy: Option[Seq[UnparsedMailboxId]],
                              onDestroyRemoveEmails: 
Option[RemoveEmailsOnDestroy])
 
@@ -71,7 +71,7 @@ case class MailboxSetResponse(accountId: AccountId,
                               updated: Option[Map[MailboxId, 
MailboxUpdateResponse]],
                               destroyed: Option[Seq[MailboxId]],
                               notCreated: Option[Map[MailboxCreationId, 
MailboxSetError]],
-                              notUpdated: Option[Map[MailboxId, 
MailboxSetError]],
+                              notUpdated: Option[Map[UnparsedMailboxId, 
MailboxSetError]],
                               notDestroyed: Option[Map[UnparsedMailboxId, 
MailboxSetError]])
 
 object MailboxSetError {
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
index 81fc67d..e774a0b 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
+++ 
b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/method/MailboxSetMethod.scala
@@ -116,7 +116,7 @@ case class DeletionResults(results: Seq[DeletionResult]) {
 
 sealed trait UpdateResult
 case class UpdateSuccess(mailboxId: MailboxId) extends UpdateResult
-case class UpdateFailure(mailboxId: MailboxId, exception: Throwable) extends 
UpdateResult {
+case class UpdateFailure(mailboxId: UnparsedMailboxId, exception: Throwable) 
extends UpdateResult {
   def asMailboxSetError: MailboxSetError = exception match {
     case _ => 
MailboxSetError.serverFail(Some(SetErrorDescription(exception.getMessage)), 
None)
   }
@@ -127,7 +127,7 @@ case class UpdateResults(results: Seq[UpdateResult]) {
       case success: UpdateSuccess => Some((success.mailboxId, 
MailboxSetResponse.empty))
       case _ => None
     }).toMap
-  def notUpdated: Map[MailboxId, MailboxSetError] = results.flatMap(result => 
result match {
+  def notUpdated: Map[UnparsedMailboxId, MailboxSetError] = 
results.flatMap(result => result match {
     case failure: UpdateFailure => Some(failure.mailboxId, 
failure.asMailboxSetError)
     case _ => None
   }).toMap
@@ -157,8 +157,11 @@ class MailboxSetMethod @Inject()(serializer: Serializer,
                               processingContext: ProcessingContext): 
SMono[UpdateResults] = {
     SFlux.fromIterable(mailboxSetRequest.update.getOrElse(Seq()))
       .flatMap({
-        case (mailboxId: MailboxId, patch: MailboxPatchObject) => 
updateMailbox(mailboxSession, mailboxId, patch)
-          .onErrorResume(e => SMono.just(UpdateFailure(mailboxId, e)))
+        case (unparsedMailboxId: UnparsedMailboxId, patch: MailboxPatchObject) 
=>
+          processingContext.resolveMailboxId(unparsedMailboxId, 
mailboxIdFactory).fold(
+              e => SMono.just(UpdateFailure(unparsedMailboxId, e)),
+              mailboxId => updateMailbox(mailboxSession, mailboxId, patch))
+            .onErrorResume(e => SMono.just(UpdateFailure(unparsedMailboxId, 
e)))
       })
       .collectSeq()
       .map(UpdateResults)
@@ -181,7 +184,7 @@ class MailboxSetMethod @Inject()(serializer: Serializer,
 
     def renameMailbox: SMono[UpdateResult] = updateMailboxPath(maiboxId, 
maybeNameUpdate, mailboxSession)
 
-    maybeParseException.map(e => 
SMono.just[UpdateResult](UpdateFailure(maiboxId, e)))
+    maybeParseException.map(e => SMono.raiseError[UpdateResult](e))
       .getOrElse(renameMailbox)
   }
 


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

Reply via email to