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 2026/07/15 10:17:31 UTC
(james-project) 16/39: [BUILD] QuotaChangesMethodContract: isolate using different users
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 <hq...@linagora.com>
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: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org