This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch 3.6.x in repository https://gitbox.apache.org/repos/asf/james-project.git
commit dc43544821c59bd194566d792cc48fc3f8ecf827 Author: Benoit Tellier <[email protected]> AuthorDate: Fri Apr 9 13:18:07 2021 +0700 JAMES-3558 JMAP Email/changes: moves should be considered as updates --- .../contract/EmailChangesMethodContract.scala | 92 +++++++++++++++++++++- .../james/jmap/change/MailboxChangeListener.scala | 6 +- .../jmap/change/MailboxChangeListenerTest.scala | 2 +- 3 files changed, 94 insertions(+), 6 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/EmailChangesMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailChangesMethodContract.scala index 404019e..80f7306 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailChangesMethodContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailChangesMethodContract.scala @@ -24,7 +24,7 @@ import java.time.Duration import java.util.concurrent.TimeUnit import io.netty.handler.codec.http.HttpHeaderNames.ACCEPT -import io.restassured.RestAssured.{`given`, requestSpecification} +import io.restassured.RestAssured.{`given`, `with`, requestSpecification} import io.restassured.builder.ResponseSpecBuilder import io.restassured.http.ContentType.JSON import javax.mail.Flags @@ -38,7 +38,7 @@ import org.apache.james.jmap.api.model.AccountId import org.apache.james.jmap.core.ResponseObject.SESSION_STATE import org.apache.james.jmap.draft.JmapGuiceProbe import org.apache.james.jmap.http.UserCredential -import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ANDRE, ANDRE_ACCOUNT_ID, ANDRE_PASSWORD, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder} +import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ACCOUNT_ID, ANDRE, ANDRE_ACCOUNT_ID, ANDRE_PASSWORD, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder} import org.apache.james.mailbox.MessageManager.AppendCommand import org.apache.james.mailbox.model.MailboxACL.Right import org.apache.james.mailbox.model.{MailboxACL, MailboxPath, MessageId} @@ -198,6 +198,94 @@ trait EmailChangesMethodContract { } @Test + def shouldReturnUpdatedWhenMessageMove(server: GuiceJamesServer): Unit = { + val mailboxProbe: MailboxProbeImpl = server.getProbe(classOf[MailboxProbeImpl]) + val path: MailboxPath = MailboxPath.forUser(BOB, "mailbox1") + + val mailboxId1 = mailboxProbe.createMailbox(path) + val mailboxId2 = mailboxProbe.createMailbox(MailboxPath.forUser(BOB, "mailbox2")) + + val message: Message = Message.Builder + .of + .setSubject("test") + .setBody("testmail", StandardCharsets.UTF_8) + .build + val messageId: MessageId = mailboxProbe.appendMessage(BOB.asString(), path, AppendCommand.from(message)).getMessageId + + val oldState: State = waitForNextState(server, AccountId.fromUsername(BOB), State.INITIAL) + + val updateEmail = + s"""{ + | "using": [ + | "urn:ietf:params:jmap:core", + | "urn:ietf:params:jmap:mail"], + | "methodCalls": [ + | ["Email/set", + | { + | "accountId": "$ACCOUNT_ID", + | "update": { + | "${messageId.serialize}":{ + | "mailboxIds": { + | "${mailboxId2.serialize()}": true + | } + | } + | } + | }, + | "c1"]] + |}""".stripMargin + + `with`() + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(updateEmail) + .post + .`then` + .statusCode(SC_OK) + .contentType(JSON) + .extract + .body + .asString + + val request = + s"""{ + | "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"], + | "methodCalls": [[ + | "Email/changes", + | { + | "accountId": "$ACCOUNT_ID", + | "sinceState": "${oldState.getValue}" + | }, + | "c1"]] + |}""".stripMargin + + awaitAtMostTenSeconds.untilAsserted { () => + val response = `given` + .header(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) + .body(request) + .when + .post + .`then` + .statusCode(SC_OK) + .contentType(JSON) + .extract + .body + .asString + + assertThatJson(response) + .whenIgnoringPaths("methodResponses[0][1].newState") + .inPath("methodResponses[0][1]") + .isEqualTo( + s"""{ + | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "oldState": "${oldState.getValue}", + | "hasMoreChanges": false, + | "created": ["${messageId.serialize()}"], + | "updated": ["${messageId.serialize()}"], + | "destroyed": [] + |}""".stripMargin) + } + } + + @Test def emailChangesShouldReturnUpdatedChangesWhenRemoveFlags(server: GuiceJamesServer): Unit = { val mailboxProbe: MailboxProbeImpl = server.getProbe(classOf[MailboxProbeImpl]) val path: MailboxPath = MailboxPath.forUser(BOB, "mailbox1") diff --git a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala index 8a5f7e2..3fc846a 100644 --- a/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala +++ b/server/protocols/jmap-rfc-8621/src/main/scala/org/apache/james/jmap/change/MailboxChangeListener.scala @@ -89,9 +89,9 @@ case class MailboxChangeListener @Inject() (@Named(InjectionKeys.JMAP) eventBus: mailboxChangeFactory.fromFlagsUpdated(flagsUpdated, now, sharees).asScala .concat(emailChangeFactory.fromFlagsUpdated(flagsUpdated, now, sharees).asScala) case expunged: Expunged => - val sharees = getSharees(mailboxId, username).asJava - mailboxChangeFactory.fromExpunged(expunged, now, sharees).asScala - .concat(emailChangeFactory.fromExpunged(expunged, now, sharees).asScala) + val sharees = getSharees(mailboxId, username) + mailboxChangeFactory.fromExpunged(expunged, now, sharees.asJava).asScala + .concat(emailChangeFactory.fromExpunged(expunged, now, sharees.map(_.getIdentifier).map(Username.of).asJava).asScala) }) .flatMap(saveChangeEvent, DEFAULT_CONCURRENCY) .`then`() diff --git a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/change/MailboxChangeListenerTest.scala b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/change/MailboxChangeListenerTest.scala index 17a91a5..23e5a2e 100644 --- a/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/change/MailboxChangeListenerTest.scala +++ b/server/protocols/jmap-rfc-8621/src/test/scala/org/apache/james/jmap/change/MailboxChangeListenerTest.scala @@ -72,7 +72,7 @@ class MailboxChangeListenerTest { stateFactory = new State.DefaultFactory mailboxChangeFactory = new MailboxChange.Factory(stateFactory) mailboxChangeRepository = new MemoryMailboxChangeRepository() - emailChangeFactory = new EmailChange.Factory(stateFactory) + emailChangeFactory = new EmailChange.Factory(stateFactory, resources.getMessageIdManager, resources.getMailboxManager) emailChangeRepository = new MemoryEmailChangeRepository() val eventBus = new EventBus { override def register(listener: EventListener.ReactiveEventListener, key: RegistrationKey): Publisher[Registration] = Mono.empty() --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
