This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit abe7afbdefc134969fb5be9c04b65a3a9a50e6a4 Author: Quan Tran <[email protected]> AuthorDate: Mon Jul 13 20:00:59 2026 +0700 [BUILD] QuotaChangesMethodContract: isolate using different users --- .../DistributedQuotaChangesMethodTest.java | 2 +- .../contract/QuotaChangesMethodContract.scala | 87 +++++++++++++++------- .../memory/MemoryQuotaChangesMethodTest.java | 2 +- .../postgres/PostgresQuotaChangesMethodTest.java | 2 +- 4 files changed, 62 insertions(+), 31 deletions(-) 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/DistributedQuotaChangesMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaChangesMethodTest.java index 1245a3a8b5..d5c77b089b 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaChangesMethodTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/distributed-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/distributed/DistributedQuotaChangesMethodTest.java @@ -21,6 +21,6 @@ package org.apache.james.jmap.rfc8621.distributed; import org.apache.james.jmap.rfc8621.contract.QuotaChangesMethodContract; -public class DistributedQuotaChangesMethodTest extends DistributedBase implements QuotaChangesMethodContract { +public class DistributedQuotaChangesMethodTest extends PerClassDistributedBase implements QuotaChangesMethodContract { } 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/QuotaChangesMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaChangesMethodContract.scala index bf940414ba..d01349c119 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaChangesMethodContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/QuotaChangesMethodContract.scala @@ -21,19 +21,24 @@ package org.apache.james.jmap.rfc8621.contract import java.nio.charset.StandardCharsets import java.time.Duration +import java.util.UUID import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicReference +import com.google.common.hash.Hashing import io.netty.handler.codec.http.HttpHeaderNames.ACCEPT import io.restassured.RestAssured.{`given`, requestSpecification} 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.core.Username import org.apache.james.core.quota.QuotaCountLimit import org.apache.james.jmap.core.ResponseObject.SESSION_STATE import org.apache.james.jmap.core.UuidState.INSTANCE import org.apache.james.jmap.http.UserCredential -import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ANDRE, ANDRE_PASSWORD, BOB, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder} +import org.apache.james.jmap.mail.{CountResourceType, QuotaIdFactory} +import org.apache.james.jmap.rfc8621.contract.Fixture.{ACCEPT_RFC8621_VERSION_HEADER, ANDRE_PASSWORD, BOB_PASSWORD, DOMAIN, authScheme, baseRequestSpecBuilder} import org.apache.james.mailbox.MessageManager.AppendCommand import org.apache.james.mailbox.model.MailboxACL.Right.Read import org.apache.james.mailbox.model.{MailboxACL, MailboxPath} @@ -45,7 +50,21 @@ import org.awaitility.Awaitility import org.junit.jupiter.api.{BeforeEach, Test} +object QuotaChangesMethodContract { + case class TestContext(bobUsername: Username, bobAccountId: String, andreUsername: Username) + + val currentContext: AtomicReference[TestContext] = new AtomicReference[TestContext]() +} + trait QuotaChangesMethodContract { + import QuotaChangesMethodContract.{TestContext, currentContext} + + def bobUsername: Username = currentContext.get().bobUsername + def bobAccountId: String = currentContext.get().bobAccountId + def andreUsername: Username = currentContext.get().andreUsername + + private def accountId(username: Username): String = + Hashing.sha256().hashString(username.asString(), StandardCharsets.UTF_8).toString private lazy val awaitAtMostTenSeconds = Awaitility.`with` .await @@ -54,14 +73,19 @@ trait QuotaChangesMethodContract { @BeforeEach def setUp(server: GuiceJamesServer): Unit = { + val uniqueSuffix = UUID.randomUUID().toString.replace("-", "").take(8) + val bob = Username.fromLocalPartWithDomain(s"bob$uniqueSuffix", DOMAIN) + val andre = Username.fromLocalPartWithDomain(s"andre$uniqueSuffix", DOMAIN) + currentContext.set(TestContext(bob, accountId(bob), andre)) + server.getProbe(classOf[DataProbeImpl]) .fluent .addDomain(DOMAIN.asString) - .addUser(BOB.asString, BOB_PASSWORD) - .addUser(ANDRE.asString, ANDRE_PASSWORD) + .addUser(bob.asString, BOB_PASSWORD) + .addUser(andre.asString, ANDRE_PASSWORD) requestSpecification = baseRequestSpecBuilder(server) - .setAuth(authScheme(UserCredential(BOB, BOB_PASSWORD))) + .setAuth(authScheme(UserCredential(bob, BOB_PASSWORD))) .addHeader(ACCEPT.toString, ACCEPT_RFC8621_VERSION_HEADER) .build } @@ -69,7 +93,7 @@ trait QuotaChangesMethodContract { @Test def quotaChangeShouldReturnCorrectResponse(server: GuiceJamesServer): Unit = { val quotaProbe = server.getProbe(classOf[QuotaProbesImpl]) - val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(BOB)) + val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(bobUsername)) quotaProbe.setMaxMessageCount(bobQuotaRoot, QuotaCountLimit.count(100L)) val response = `given` @@ -81,7 +105,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "${INSTANCE.value}" | }, | "c1"]] @@ -95,32 +119,39 @@ trait QuotaChangesMethodContract { .body .asString - assertThatJson(response).isEqualTo( + assertThatJson(response) + .whenIgnoringPaths("methodResponses[0][1].newState", "methodResponses[0][1].updated") + .isEqualTo( s"""{ | "sessionState": "${SESSION_STATE.value}", | "methodResponses": [ | [ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "oldState": "${INSTANCE.value}", - | "newState": "84c40a2e-76a1-3f84-a1e8-862104c7a697", + | "newState": "", | "hasMoreChanges": false, | "updatedProperties": null, | "created": [], - | "updated": ["08417be420b6dd6fa77d48fb2438e0d19108cd29424844bb109b52d356fab528"], + | "updated": [], | "destroyed": [] | }, | "c1" | ] - | ] + | ] |}""".stripMargin) + + val responseObject = play.api.libs.json.Json.parse(response) + assertThat((responseObject \ "methodResponses" \ 0 \ 1 \ "newState").as[String]).isNotEqualTo(INSTANCE.value) + assertThat((responseObject \ "methodResponses" \ 0 \ 1 \ "updated").as[Seq[String]]) + .isEqualTo(Seq(QuotaIdFactory.from(bobQuotaRoot, CountResourceType).value)) } @Test def quotaChangeShouldReturnSameResponseWhenSameRequest(server: GuiceJamesServer): Unit = { val quotaProbe = server.getProbe(classOf[QuotaProbesImpl]) - val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(BOB)) + val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(bobUsername)) quotaProbe.setMaxMessageCount(bobQuotaRoot, QuotaCountLimit.count(100L)) val response1 = `given` @@ -132,7 +163,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "${INSTANCE.value}" | }, | "c1"]] @@ -155,7 +186,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "${INSTANCE.value}" | }, | "c1"]] @@ -175,7 +206,7 @@ trait QuotaChangesMethodContract { @Test def hasMoreChangesShouldBeFalseWhenNoQuotaChanges(server: GuiceJamesServer): Unit = { val quotaProbe = server.getProbe(classOf[QuotaProbesImpl]) - val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(BOB)) + val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(bobUsername)) quotaProbe.setMaxMessageCount(bobQuotaRoot, QuotaCountLimit.count(100L)) val newState: String = getLastState() @@ -189,7 +220,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "${newState}" | }, | "c1"]] @@ -210,7 +241,7 @@ trait QuotaChangesMethodContract { | [ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "oldState": "${newState}", | "newState": "${newState}", | "hasMoreChanges": false, @@ -229,15 +260,15 @@ trait QuotaChangesMethodContract { @Test def stateShouldBeChangedWhenQuotaIsUpdated(server: GuiceJamesServer): Unit = { val quotaProbe = server.getProbe(classOf[QuotaProbesImpl]) - val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(BOB)) + val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(bobUsername)) quotaProbe.setMaxMessageCount(bobQuotaRoot, QuotaCountLimit.count(100L)) - server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(BOB)) + server.getProbe(classOf[MailboxProbeImpl]).createMailbox(MailboxPath.inbox(bobUsername)) val newState: String = getLastState() // update quota usage server.getProbe(classOf[MailboxProbeImpl]) - .appendMessage(BOB.asString(), MailboxPath.inbox(BOB), AppendCommand.from(Message.Builder + .appendMessage(bobUsername.asString(), MailboxPath.inbox(bobUsername), AppendCommand.from(Message.Builder .of .setSubject("test") .setBody("testmail", StandardCharsets.UTF_8) @@ -258,7 +289,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "${INSTANCE.value}" | }, | "c1"]] @@ -320,7 +351,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6" + | "accountId": "$bobAccountId" | }, | "c1"]] |}""".stripMargin) @@ -360,7 +391,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "invaLid@" | }, | "c1"]] @@ -466,14 +497,14 @@ trait QuotaChangesMethodContract { @Test def quotaChangesShouldReturnDifferenceStateWhenProvideDelegatedMailbox(server: GuiceJamesServer): Unit = { val quotaProbe = server.getProbe(classOf[QuotaProbesImpl]) - val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(BOB)) + val bobQuotaRoot = quotaProbe.getQuotaRoot(MailboxPath.inbox(bobUsername)) quotaProbe.setMaxMessageCount(bobQuotaRoot, QuotaCountLimit.count(100L)) // setup delegated Mailbox - val andreMailbox = MailboxPath.forUser(ANDRE, "mailbox") + val andreMailbox = MailboxPath.forUser(andreUsername, "mailbox") val mailboxId = server.getProbe(classOf[MailboxProbeImpl]).createMailbox(andreMailbox) server.getProbe(classOf[ACLProbeImpl]) - .replaceRights(andreMailbox, BOB.asString, new MailboxACL.Rfc4314Rights(Read)) + .replaceRights(andreMailbox, bobUsername.asString, new MailboxACL.Rfc4314Rights(Read)) quotaProbe.setMaxMessageCount(quotaProbe.getQuotaRoot(andreMailbox), QuotaCountLimit.count(88L)) val stateWithOutShareCapability: String = `given` @@ -485,7 +516,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "${INSTANCE.value}" | }, | "c1"]] @@ -509,7 +540,7 @@ trait QuotaChangesMethodContract { | "methodCalls": [[ | "Quota/changes", | { - | "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6", + | "accountId": "$bobAccountId", | "sinceState": "${INSTANCE.value}" | }, | "c1"]] 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/MemoryQuotaChangesMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaChangesMethodTest.java index 73c4593b61..30be022c1b 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaChangesMethodTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/memory-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/memory/MemoryQuotaChangesMethodTest.java @@ -21,6 +21,6 @@ package org.apache.james.jmap.rfc8621.memory; import org.apache.james.jmap.rfc8621.contract.QuotaChangesMethodContract; -public class MemoryQuotaChangesMethodTest extends MemoryBase implements QuotaChangesMethodContract { +public class MemoryQuotaChangesMethodTest extends PerClassMemoryBase implements QuotaChangesMethodContract { } diff --git a/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresQuotaChangesMethodTest.java b/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresQuotaChangesMethodTest.java index f83c761927..939e15464e 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresQuotaChangesMethodTest.java +++ b/server/protocols/jmap-rfc-8621-integration-tests/postgres-jmap-rfc-8621-integration-tests/src/test/java/org/apache/james/jmap/rfc8621/postgres/PostgresQuotaChangesMethodTest.java @@ -21,5 +21,5 @@ package org.apache.james.jmap.rfc8621.postgres; import org.apache.james.jmap.rfc8621.contract.QuotaChangesMethodContract; -public class PostgresQuotaChangesMethodTest extends PostgresBase implements QuotaChangesMethodContract { +public class PostgresQuotaChangesMethodTest extends PerClassPostgresBase implements QuotaChangesMethodContract { } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
