JAMES-4025 Rewrite some tests of JMAP draft on top of JMAP RFC-8621 (module: spamassassin)
diff --git a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinContract.java b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinContract.java
index 35fb752..2846980 100644
--- a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinContract.java
+++ b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/SpamAssassinContract.java
@@ -24,32 +24,30 @@
import static io.restassured.RestAssured.with;
import static io.restassured.config.EncoderConfig.encoderConfig;
import static io.restassured.config.RestAssuredConfig.newConfig;
-import static org.apache.james.jmap.HttpJmapAuthentication.authenticateJamesUser;
-import static org.apache.james.jmap.JMAPTestingConstants.ARGUMENTS;
+import static io.restassured.http.ContentType.JSON;
import static org.apache.james.jmap.JMAPTestingConstants.LOCALHOST_IP;
-import static org.apache.james.jmap.JMAPTestingConstants.NAME;
import static org.apache.james.jmap.JMAPTestingConstants.calmlyAwait;
+import static org.apache.james.jmap.JmapRFCCommonRequests.ACCEPT_JMAP_RFC_HEADER;
+import static org.apache.james.jmap.JmapRFCCommonRequests.UserCredential;
+import static org.apache.james.jmap.JmapRFCCommonRequests.getMailboxId;
+import static org.apache.james.jmap.JmapRFCCommonRequests.getUserCredential;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Durations.ONE_MINUTE;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.notNullValue;
import java.nio.charset.StandardCharsets;
import java.util.List;
-import java.util.Map;
+import java.util.function.Consumer;
-import org.apache.http.client.utils.URIBuilder;
import org.apache.james.GuiceJamesServer;
-import org.apache.james.core.Username;
-import org.apache.james.jmap.AccessToken;
-import org.apache.james.jmap.LocalHostURIBuilder;
+import org.apache.james.jmap.JmapRFCCommonRequests;
import org.apache.james.jmap.draft.JmapGuiceProbe;
import org.apache.james.mailbox.Role;
import org.apache.james.modules.protocols.ImapGuiceProbe;
-import org.apache.james.util.Port;
import org.apache.james.utils.DataProbeImpl;
import org.apache.james.utils.SpoolerProbe;
import org.apache.james.utils.TestIMAPClient;
+import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -77,6 +75,7 @@
.setAccept(ContentType.JSON)
.setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(StandardCharsets.UTF_8)))
.setPort(jamesServer.getProbe(JmapGuiceProbe.class).getJmapPort().getValue())
+ .addHeader(ACCEPT_JMAP_RFC_HEADER.getName(), ACCEPT_JMAP_RFC_HEADER.getValue())
.build();
RestAssured.defaultParser = Parser.JSON;
@@ -95,79 +94,71 @@
spamAssassin.clear(ALICE);
}
- default AccessToken accessTokenFor(GuiceJamesServer james, String user, String password) {
- return authenticateJamesUser(baseUri(james), Username.of(user), password);
- }
-
@Test
default void spamShouldBeDeliveredInSpamMailboxWhenSameMessageHasAlreadyBeenMovedToSpam(
GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
// Alice is moving this message to Spam -> learning in SpamAssassin
- List<String> messageIds = with()
- .header("Authorization", aliceAccessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + getInboxId(aliceAccessToken) + "\"]}}, \"#0\"]]")
+ String aliceInboxId = JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.INBOX);
+ List<String> msgIds = JmapRFCCommonRequests.listMessageIdsInMailbox(aliceCredential, aliceInboxId);
+
+ String aliceSpamMailboxId = JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.SPAM);
+
+ Consumer<String> moveMessageToSpamMailbox = messageId -> given()
+ .auth().basic(aliceCredential.username().asString(), aliceCredential.password())
+ .body("""
+ {
+ "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+ "methodCalls": [
+ ["Email/set", {
+ "accountId": "%s",
+ "update": {
+ "%s":{
+ "mailboxIds": { "%s" : true}
+ }
+ }
+ }, "c1"]]
+ }""".formatted(aliceCredential.accountId(), messageId, aliceSpamMailboxId))
.when()
.post("/jmap")
.then()
.statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1))
- .extract()
- .path(ARGUMENTS + ".messageIds");
+ .contentType(JSON);
- messageIds.parallelStream()
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getSpamId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ msgIds.forEach(moveMessageToSpamMailbox);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice Spam mailbox (she now must have 2 messages in her Spam mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 2));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 2));
}
@Test
default void imapCopiesToSpamMailboxShouldBeConsideredAsSpam(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ bobSendSpamEmailToAlice(bobCredential);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
@@ -179,33 +170,25 @@
testIMAPClient.copyFirstMessage("Spam");
}
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice Spam mailbox (she now must have 2 messages in her Spam mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 2));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 2));
}
@Test
default void imapMovesToSpamMailboxShouldBeConsideredAsSpam(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ bobSendSpamEmailToAlice(bobCredential);
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
try (TestIMAPClient testIMAPClient = new TestIMAPClient()) {
@@ -215,189 +198,141 @@
testIMAPClient.moveFirstMessage("Spam");
}
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice Spam mailbox (she now must have 2 messages in her Spam mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 2));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 2));
}
@Test
default void spamAssassinShouldForgetMessagesMovedOutOfSpamFolderUsingJMAP(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ bobSendSpamEmailToAlice(bobCredential);
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
// Alice is moving this message to Spam -> learning in SpamAssassin
- List<String> messageIds = with()
- .header("Authorization", aliceAccessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + getInboxId(aliceAccessToken) + "\"]}}, \"#0\"]]")
+ String aliceInboxId = JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.INBOX);
+ List<String> msgIds = JmapRFCCommonRequests.listMessageIdsInMailbox(aliceCredential, aliceInboxId);
+
+ String aliceSpamMailboxId = JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.SPAM);
+
+ Consumer<String> moveMessageToSpamMailbox = messageId -> given()
+ .auth().basic(aliceCredential.username().asString(), aliceCredential.password())
+ .body("""
+ {
+ "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+ "methodCalls": [
+ ["Email/set", {
+ "accountId": "%s",
+ "update": {
+ "%s":{
+ "mailboxIds": { "%s" : true}
+ }
+ }
+ }, "c1"]]
+ }""".formatted(aliceCredential.accountId(), messageId, aliceSpamMailboxId))
.when()
.post("/jmap")
.then()
.statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1))
- .extract()
- .path(ARGUMENTS + ".messageIds");
+ .contentType(JSON);
- messageIds.parallelStream()
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getSpamId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ msgIds.forEach(moveMessageToSpamMailbox);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Alice is moving this message out of Spam -> forgetting in SpamAssassin
- messageIds
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getInboxId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ Consumer<String> moveMessageOutOfSpamMailbox = messageId -> given()
+ .auth().basic(aliceCredential.username().asString(), aliceCredential.password())
+ .body("""
+ {
+ "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+ "methodCalls": [
+ ["Email/set", {
+ "accountId": "%s",
+ "update": {
+ "%s":{
+ "mailboxIds": { "%s" : true}
+ }
+ }
+ }, "c1"]]
+ }""".formatted(aliceCredential.accountId(), messageId, aliceInboxId))
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200)
+ .contentType(JSON);
+ msgIds.forEach(moveMessageOutOfSpamMailbox);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice INBOX mailbox (she now must have 2 messages in her Inbox mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 2));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 2));
}
@Test
default void movingAMailToTrashShouldNotImpactSpamassassinLearning(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ bobSendSpamEmailToAlice(bobCredential);
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
// Alice is moving this message to Spam -> learning in SpamAssassin
- List<String> messageIds = with()
- .header("Authorization", aliceAccessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + getInboxId(aliceAccessToken) + "\"]}}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1))
- .extract()
- .path(ARGUMENTS + ".messageIds");
+ String aliceInboxId = JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.INBOX);
+ List<String> msgIds = JmapRFCCommonRequests.listMessageIdsInMailbox(aliceCredential, aliceInboxId);
- messageIds.parallelStream()
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getSpamId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ String aliceSpamMailboxId = JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.SPAM);
+ moveMessagesToNewMailbox(msgIds, aliceSpamMailboxId, aliceCredential);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Alice is moving this message to trash
- messageIds
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getTrashId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getTrashId(aliceAccessToken), 1));
+ moveMessagesToNewMailbox(msgIds, getTrashId(aliceCredential), aliceCredential);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getTrashId(aliceCredential), 1));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice Spam mailbox (she now must have 1 messages in her Spam mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
}
@Test
default void spamAssassinShouldForgetMessagesMovedOutOfSpamFolderUsingIMAP(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ bobSendSpamEmailToAlice(bobCredential);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
// Alice is moving this message to Spam -> learning in SpamAssassin
- List<String> messageIds = with()
- .header("Authorization", aliceAccessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + getInboxId(aliceAccessToken) + "\"]}}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1))
- .extract()
- .path(ARGUMENTS + ".messageIds");
-
- messageIds.parallelStream()
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getSpamId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ List<String> messageIds = JmapRFCCommonRequests.listMessageIdsInMailbox(aliceCredential, JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.INBOX));
+ moveMessagesToNewMailbox(messageIds, getMailboxId(aliceCredential, Role.SPAM), aliceCredential);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Alice is moving this message out of Spam -> forgetting in SpamAssassin
try (TestIMAPClient testIMAPClient = new TestIMAPClient()) {
@@ -407,59 +342,32 @@
testIMAPClient.moveFirstMessage(TestIMAPClient.INBOX);
}
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice INBOX mailbox (she now must have 2 messages in her Inbox mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 2));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 2));
}
@Test
default void expungingSpamMessageShouldNotImpactSpamAssassinState(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ bobSendSpamEmailToAlice(bobCredential);
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
// Alice is moving this message to Spam -> learning in SpamAssassin
- List<String> messageIds = with()
- .header("Authorization", aliceAccessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + getInboxId(aliceAccessToken) + "\"]}}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1))
- .extract()
- .path(ARGUMENTS + ".messageIds");
+ List<String> messageIds = JmapRFCCommonRequests.listMessageIdsInMailbox(aliceCredential, JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.INBOX));
+ moveMessagesToNewMailbox(messageIds, getMailboxId(aliceCredential, Role.SPAM), aliceCredential);
- messageIds
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getSpamId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Alice is deleting this message
try (TestIMAPClient testIMAPClient = new TestIMAPClient()) {
@@ -470,222 +378,210 @@
testIMAPClient.setFlagsForAllMessagesInMailbox("\\Deleted");
testIMAPClient.expunge();
}
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 0));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 0));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice SPAM mailbox (she now must have 1 messages in her Spam mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
}
@Test
default void deletingSpamMessageShouldNotImpactSpamAssassinState(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
// Bob is sending a message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
+ bobSendSpamEmailToAlice(bobCredential);
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertEveryListenerGotCalled(jamesServer));
// Alice is moving this message to Spam -> learning in SpamAssassin
- List<String> messageIds = with()
- .header("Authorization", aliceAccessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + getInboxId(aliceAccessToken) + "\"]}}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1))
- .extract()
- .path(ARGUMENTS + ".messageIds");
+ List<String> messageIds = JmapRFCCommonRequests.listMessageIdsInMailbox(aliceCredential, JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.INBOX));
+ moveMessagesToNewMailbox(messageIds, getMailboxId(aliceCredential, Role.SPAM), aliceCredential);
- messageIds.parallelStream()
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getSpamId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Alice is deleting this message
- messageIds
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"destroy\": [\"%s\"] }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".destroyed", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 0));
+ JmapRFCCommonRequests.deleteMessages(aliceCredential, messageIds);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 0));
// Bob is sending again the same message to Alice
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreate(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendSpamEmailToAlice(bobCredential);
// This message is delivered in Alice SPAM mailbox (she now must have 1 messages in her Spam mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
}
- default String setMessageCreate(AccessToken accessToken) {
- return "[" +
- " [" +
- " \"setMessages\"," +
- " {" +
- " \"create\": { \"creationId1337\" : {" +
- " \"from\": { \"email\": \"" + BOB + "\"}," +
- " \"to\": [{ \"name\": \"recipient\", \"email\": \"" + ALICE + "\"}]," +
- " \"subject\": \"Happy News\"," +
- " \"textBody\": \"This is a SPAM!!!\r\n\r\n\"," +
- " \"mailboxIds\": [\"" + getOutboxId(accessToken) + "\"]" +
- " }}" +
- " }," +
- " \"#0\"" +
- " ]" +
- "]";
+ default void bobSendSpamEmailToAlice(UserCredential bobCredential) {
+ String bobOutboxId = JmapRFCCommonRequests.getOutboxId(bobCredential);
+ String requestBody =
+ "{" +
+ " \"using\": [\"urn:ietf:params:jmap:core\", \"urn:ietf:params:jmap:mail\", \"urn:ietf:params:jmap:submission\"]," +
+ " \"methodCalls\": [" +
+ " [\"Email/set\", {" +
+ " \"accountId\": \"" + bobCredential.accountId() + "\"," +
+ " \"create\": {" +
+ " \"e1526\": {" +
+ " \"mailboxIds\": { \"" + bobOutboxId + "\": true }," +
+ " \"subject\": \"Happy News\"," +
+ " \"textBody\": [{" +
+ " \"partId\": \"a49d\"," +
+ " \"type\": \"text/plain\"" +
+ " }]," +
+ " \"bodyValues\": {" +
+ " \"a49d\": {" +
+ " \"value\": \"This is a SPAM!!!\"" +
+ " }" +
+ " }," +
+ " \"to\": [{" +
+ " \"email\": \"" + ALICE + "\"" +
+ " }]," +
+ " \"from\": [{" +
+ " \"email\": \"" + BOB + "\"" +
+ " }]" +
+ " }" +
+ " }" +
+ " }, \"c1\"]," +
+ " [\"Email/get\", {" +
+ " \"accountId\": \"" + bobCredential.accountId() + "\"," +
+ " \"ids\": [\"#e1526\"]," +
+ " \"properties\": [\"sentAt\"]" +
+ " }, \"c2\"]," +
+ " [\"EmailSubmission/set\", {" +
+ " \"accountId\": \"" + bobCredential.accountId() + "\"," +
+ " \"create\": {" +
+ " \"k1490\": {" +
+ " \"emailId\": \"#e1526\"," +
+ " \"envelope\": {" +
+ " \"mailFrom\": {\"email\": \"" + BOB + "\"}," +
+ " \"rcptTo\": [{" +
+ " \"email\": \"" + ALICE + "\"" +
+ " }]" +
+ " }" +
+ " }" +
+ " }" +
+ " }, \"c3\"]" +
+ " ]" +
+ "}";
+
+ with()
+ .auth().basic(bobCredential.username().asString(), bobCredential.password())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200)
+ .contentType(JSON)
+ .body("methodResponses[2][1].created", Matchers.is(notNullValue()));
+
}
@Test
default void spamShouldBeDeliveredInSpamMailboxOrInboxWhenMultipleRecipientsConfigurations(GuiceJamesServer jamesServer,
SpamAssassinExtension.SpamAssassin spamAssassin) throws Exception {
spamAssassin.train(ALICE);
- AccessToken aliceAccessToken = accessTokenFor(jamesServer, ALICE, ALICE_PASSWORD);
- AccessToken bobAccessToken = accessTokenFor(jamesServer, BOB, BOB_PASSWORD);
- AccessToken paulAccessToken = accessTokenFor(jamesServer, PAUL, PAUL_PASSWORD);
+ UserCredential aliceCredential = getUserCredential(ALICE, ALICE_PASSWORD);
+ UserCredential bobCredential = getUserCredential(BOB, BOB_PASSWORD);
+ UserCredential paulCredential = getUserCredential(PAUL, PAUL_PASSWORD);
// Bob is sending a message to Alice & Paul
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreateToMultipleRecipients(bobAccessToken))
- .when()
- .post("/jmap");
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 1));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(paulAccessToken, getInboxId(paulAccessToken), 1));
+ String bobSendSpamEmailToAliceAndPaulRequest =
+ "{" +
+ " \"using\": [\"urn:ietf:params:jmap:core\", \"urn:ietf:params:jmap:mail\", \"urn:ietf:params:jmap:submission\"]," +
+ " \"methodCalls\": [" +
+ " [\"Email/set\", {" +
+ " \"accountId\": \"" + bobCredential.accountId() + "\"," +
+ " \"create\": {" +
+ " \"e1526\": {" +
+ " \"mailboxIds\": { \"" + JmapRFCCommonRequests.getOutboxId(bobCredential) + "\": true }," +
+ " \"subject\": \"Happy News\"," +
+ " \"textBody\": [{" +
+ " \"partId\": \"a49d\"," +
+ " \"type\": \"text/plain\"" +
+ " }]," +
+ " \"bodyValues\": {" +
+ " \"a49d\": {" +
+ " \"value\": \"This is a SPAM!!!\"" +
+ " }" +
+ " }," +
+ " \"to\": [{\"email\": \"" + ALICE + "\"}, {\"email\": \"" + PAUL + "\"}]," +
+ " \"from\": [{" +
+ " \"email\": \"" + BOB + "\"" +
+ " }]" +
+ " }" +
+ " }" +
+ " }, \"c1\"]," +
+ " [\"Email/get\", {" +
+ " \"accountId\": \"" + bobCredential.accountId() + "\"," +
+ " \"ids\": [\"#e1526\"]," +
+ " \"properties\": [\"sentAt\"]" +
+ " }, \"c2\"]," +
+ " [\"EmailSubmission/set\", {" +
+ " \"accountId\": \"" + bobCredential.accountId() + "\"," +
+ " \"create\": {" +
+ " \"k1490\": {" +
+ " \"emailId\": \"#e1526\"," +
+ " \"envelope\": {" +
+ " \"mailFrom\": {\"email\": \"" + BOB + "\"}," +
+ " \"rcptTo\": [{\"email\": \"" + ALICE + "\"}, {\"email\": \"" + PAUL + "\"}]" +
+ " }" +
+ " }" +
+ " }" +
+ " }, \"c3\"]" +
+ " ]" +
+ "}";
+
+ Consumer<String> bobSendAndEmail = requestBody -> with()
+ .auth().basic(bobCredential.username().asString(), bobCredential.password())
+ .body(requestBody)
+ .post("/jmap")
+ .then()
+ .statusCode(200)
+ .contentType(JSON)
+ .body("methodResponses[2][1].created", Matchers.is(notNullValue()));
+
+ bobSendAndEmail.accept(bobSendSpamEmailToAliceAndPaulRequest);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 1));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(paulCredential, getInboxId(paulCredential), 1));
// Alice is moving this message to Spam -> learning in SpamAssassin
- List<String> messageIds = with()
- .header("Authorization", aliceAccessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + getInboxId(aliceAccessToken) + "\"]}}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(1))
- .extract()
- .path(ARGUMENTS + ".messageIds");
-
- messageIds.parallelStream()
- .forEach(messageId -> given()
- .header("Authorization", aliceAccessToken.asString())
- .body(String.format("[[\"setMessages\", {\"update\": {\"%s\" : { \"mailboxIds\": [\"" + getSpamId(aliceAccessToken) + "\"] } } }, \"#0\"]]", messageId))
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messagesSet"))
- .body(ARGUMENTS + ".updated", hasSize(1)));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 1));
+ String aliceInboxId = JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.INBOX);
+ List<String> msgIds = JmapRFCCommonRequests.listMessageIdsInMailbox(aliceCredential, aliceInboxId);
+ moveMessagesToNewMailbox(msgIds, JmapRFCCommonRequests.getMailboxId(aliceCredential, Role.SPAM), aliceCredential);
+
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 1));
// Bob is sending again the same message to Alice & Paul
- given()
- .header("Authorization", bobAccessToken.asString())
- .body(setMessageCreateToMultipleRecipients(bobAccessToken))
- .when()
- .post("/jmap");
+ bobSendAndEmail.accept(bobSendSpamEmailToAliceAndPaulRequest);
// This message is delivered in Alice Spam mailbox (she now must have 2 messages in her Spam mailbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getSpamId(aliceAccessToken), 2));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceAccessToken, getInboxId(aliceAccessToken), 0));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getSpamId(aliceCredential), 2));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(aliceCredential, getInboxId(aliceCredential), 0));
// This message is delivered in Paul Inbox (he now must have 2 messages in his Inbox)
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(paulAccessToken, getInboxId(paulAccessToken), 2));
- calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(paulAccessToken, getSpamId(paulAccessToken), 0));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(paulCredential, getInboxId(paulCredential), 2));
+ calmlyAwait.atMost(ONE_MINUTE).untilAsserted(() -> assertMessagesFoundInMailbox(paulCredential, getSpamId(paulCredential), 0));
}
- default String setMessageCreateToMultipleRecipients(AccessToken accessToken) {
- return "[" +
- " [" +
- " \"setMessages\"," +
- " {" +
- " \"create\": { \"creationId1337\" : {" +
- " \"from\": { \"email\": \"" + BOB + "\"}," +
- " \"to\": [{ \"name\": \"alice\", \"email\": \"" + ALICE + "\"}, " +
- " { \"name\": \"paul\", \"email\": \"" + PAUL + "\"}]," +
- " \"subject\": \"Happy News\"," +
- " \"textBody\": \"This is a SPAM!!!\r\n\r\n\"," +
- " \"mailboxIds\": [\"" + getOutboxId(accessToken) + "\"]" +
- " }}" +
- " }," +
- " \"#0\"" +
- " ]" +
- "]";
+ default void assertMessagesFoundInMailbox(UserCredential userCredential, String mailboxId, int expectedNumberOfMessages) {
+ assertThat(JmapRFCCommonRequests.listMessageIdsInMailbox(userCredential, mailboxId))
+ .hasSize(expectedNumberOfMessages);
}
- default void assertMessagesFoundInMailbox(AccessToken accessToken, String mailboxId, int expectedNumberOfMessages) {
- with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMessageList\", {\"filter\":{\"inMailboxes\":[\"" + mailboxId + "\"]}}, \"#0\"]]")
- .when()
- .post("/jmap")
- .then()
- .statusCode(200)
- .body(NAME, equalTo("messageList"))
- .body(ARGUMENTS + ".messageIds", hasSize(expectedNumberOfMessages));
+ default String getInboxId(UserCredential userCredential) {
+ return JmapRFCCommonRequests.getMailboxId(userCredential, Role.INBOX);
}
- default String getMailboxId(AccessToken accessToken, Role role) {
- return getAllMailboxesIds(accessToken).stream()
- .filter(x -> x.get("role").equalsIgnoreCase(role.serialize()))
- .map(x -> x.get("id"))
- .findFirst().get();
+ default String getSpamId(UserCredential userCredential) {
+ return JmapRFCCommonRequests.getMailboxId(userCredential,Role.SPAM);
}
- default List<Map<String, String>> getAllMailboxesIds(AccessToken accessToken) {
- return with()
- .header("Authorization", accessToken.asString())
- .body("[[\"getMailboxes\", {\"properties\": [\"role\", \"id\"]}, \"#0\"]]")
- .post("/jmap")
- .andReturn()
- .body()
- .jsonPath()
- .getList(ARGUMENTS + ".list");
- }
-
- default String getInboxId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.INBOX);
- }
-
- default String getOutboxId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.OUTBOX);
- }
-
- default String getSpamId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.SPAM);
- }
-
- default String getTrashId(AccessToken accessToken) {
- return getMailboxId(accessToken, Role.TRASH);
+ default String getTrashId(UserCredential userCredential) {
+ return JmapRFCCommonRequests.getMailboxId(userCredential,Role.TRASH);
}
default void assertEveryListenerGotCalled(GuiceJamesServer jamesServer) {
@@ -694,8 +590,28 @@
.isTrue();
}
- private URIBuilder baseUri(GuiceJamesServer jamesServer) {
- return LocalHostURIBuilder.baseUri(
- Port.of(jamesServer.getProbe(JmapGuiceProbe.class).getJmapPort().getValue()));
+ private void moveMessagesToNewMailbox(List<String> messageIds, String newMailboxId, UserCredential userCredential) {
+ Consumer<String> moveMessagesToNewMailbox = messageId -> given()
+ .auth().basic(userCredential.username().asString(), userCredential.password())
+ .body("""
+ {
+ "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
+ "methodCalls": [
+ ["Email/set", {
+ "accountId": "%s",
+ "update": {
+ "%s":{
+ "mailboxIds": { "%s" : true}
+ }
+ }
+ }, "c1"]]
+ }""".formatted(userCredential.accountId(), messageId, newMailboxId))
+ .when()
+ .post("/jmap")
+ .then()
+ .statusCode(200)
+ .contentType(JSON);
+
+ messageIds.forEach(moveMessagesToNewMailbox);
}
}
diff --git a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/module/SpamAssassinTestModule.java b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/module/SpamAssassinTestModule.java
index 204bdb2..dc47244 100644
--- a/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/module/SpamAssassinTestModule.java
+++ b/third-party/spamassassin/src/test/java/org/apache/james/spamassassin/module/SpamAssassinTestModule.java
@@ -21,19 +21,16 @@
import jakarta.inject.Singleton;
-import org.apache.james.mailetcontainer.impl.MailetConfigImpl;
+import org.apache.james.jmap.event.PopulateEmailQueryViewListener;
import org.apache.james.modules.mailbox.ListenerConfiguration;
import org.apache.james.modules.mailbox.ListenersConfiguration;
-import org.apache.james.spamassassin.SpamAssassin;
import org.apache.james.spamassassin.SpamAssassinConfiguration;
import org.apache.james.spamassassin.SpamAssassinExtension;
import org.apache.james.spamassassin.SpamAssassinListener;
import org.apache.james.util.Host;
-import org.apache.james.utils.MailetConfigurationOverride;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
-import com.google.inject.multibindings.Multibinder;
public class SpamAssassinTestModule extends AbstractModule {
@@ -47,7 +44,8 @@
protected void configure() {
bind(ListenersConfiguration.class)
.toInstance(ListenersConfiguration.of(
- ListenerConfiguration.forClass(SpamAssassinListener.class.getCanonicalName())));
+ ListenerConfiguration.forClass(SpamAssassinListener.class.getCanonicalName()),
+ ListenerConfiguration.forClass(PopulateEmailQueryViewListener.class.getCanonicalName())));
}
@Provides