This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 14ec290b041dafaf7d5eb847fdcd9a9fbffb792c Author: Rene Cordier <[email protected]> AuthorDate: Thu Nov 27 16:31:46 2025 +0700 JAMES-3340 Minor refactorings --- .../projections/CassandraEmailQueryView.java | 42 +--- .../projections/PostgresEmailQueryViewDAO.java | 50 ++--- .../jmap/api/projections/EmailQueryViewUtils.java | 19 ++ .../contract/EmailQueryMethodContract.scala | 248 ++++----------------- 4 files changed, 85 insertions(+), 274 deletions(-) diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java index 4ddb6f69ab..f75b39f3f0 100644 --- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/projections/CassandraEmailQueryView.java @@ -25,7 +25,7 @@ import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.deleteFrom; import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto; import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom; import static org.apache.james.jmap.api.projections.EmailQueryViewUtils.backendLimitFetch; -import static org.apache.james.jmap.api.projections.EmailQueryViewUtils.messagesWithCollapseThreads; +import static org.apache.james.jmap.api.projections.EmailQueryViewUtils.messagesWithMaybeCollapseThreads; import static org.apache.james.jmap.cassandra.projections.table.CassandraEmailQueryViewTable.DATE_LOOKUP_TABLE; import static org.apache.james.jmap.cassandra.projections.table.CassandraEmailQueryViewTable.MAILBOX_ID; import static org.apache.james.jmap.cassandra.projections.table.CassandraEmailQueryViewTable.MESSAGE_ID; @@ -199,12 +199,8 @@ public class CassandraEmailQueryView implements EmailQueryView { .setInt(LIMIT_MARKER, backendFetchLimit.getLimit().get())) .map(asEmailEntry(SENT_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSortedBySentAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSortedBySentAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); } @Override @@ -221,12 +217,8 @@ public class CassandraEmailQueryView implements EmailQueryView { .setInt(LIMIT_MARKER, backendFetchLimit.getLimit().get())) .map(asEmailEntry(RECEIVED_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSortedByReceivedAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSortedByReceivedAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); } @Override @@ -268,12 +260,8 @@ public class CassandraEmailQueryView implements EmailQueryView { .setInt(LIMIT_MARKER, backendFetchLimit.getLimit().get())) .map(asEmailEntry(SENT_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSinceAfterSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSinceAfterSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); } @Override @@ -291,12 +279,8 @@ public class CassandraEmailQueryView implements EmailQueryView { .setInt(LIMIT_MARKER, backendFetchLimit.getLimit().get())) .map(asEmailEntry(SENT_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentBeforeSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentBeforeSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); } @Override @@ -314,12 +298,8 @@ public class CassandraEmailQueryView implements EmailQueryView { .setInt(LIMIT_MARKER, backendFetchLimit.getLimit().get())) .map(asEmailEntry(SENT_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSinceSentAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSinceSentAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); } private Function<Row, EmailEntry> asEmailEntry(CqlIdentifier dateField) { diff --git a/server/data/data-jmap-postgres/src/main/java/org/apache/james/jmap/postgres/projections/PostgresEmailQueryViewDAO.java b/server/data/data-jmap-postgres/src/main/java/org/apache/james/jmap/postgres/projections/PostgresEmailQueryViewDAO.java index a8c0296c12..ce2f235b81 100644 --- a/server/data/data-jmap-postgres/src/main/java/org/apache/james/jmap/postgres/projections/PostgresEmailQueryViewDAO.java +++ b/server/data/data-jmap-postgres/src/main/java/org/apache/james/jmap/postgres/projections/PostgresEmailQueryViewDAO.java @@ -20,7 +20,7 @@ package org.apache.james.jmap.postgres.projections; import static org.apache.james.jmap.api.projections.EmailQueryViewUtils.backendLimitFetch; -import static org.apache.james.jmap.api.projections.EmailQueryViewUtils.messagesWithCollapseThreads; +import static org.apache.james.jmap.api.projections.EmailQueryViewUtils.messagesWithMaybeCollapseThreads; import static org.apache.james.jmap.postgres.projections.PostgresEmailQueryViewDataDefinition.PostgresEmailQueryViewTable.MAILBOX_ID; import static org.apache.james.jmap.postgres.projections.PostgresEmailQueryViewDataDefinition.PostgresEmailQueryViewTable.MESSAGE_ID; import static org.apache.james.jmap.postgres.projections.PostgresEmailQueryViewDataDefinition.PostgresEmailQueryViewTable.PK_CONSTRAINT_NAME; @@ -77,12 +77,8 @@ public class PostgresEmailQueryViewDAO { .limit(backendFetchLimit.getLimit().get()))) .map(asEmailEntry(SENT_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSortedBySentAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSortedBySentAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); } public Flux<MessageId> listMailboxContentSortedByReceivedAt(PostgresMailboxId mailboxId, Limit limit, boolean collapseThreads) { @@ -101,12 +97,8 @@ public class PostgresEmailQueryViewDAO { .limit(backendFetchLimit.getLimit().get()))) .map(asEmailEntry(RECEIVED_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSortedByReceivedAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSortedByReceivedAtWithBackendLimit(mailboxId, limit, collapseThreads, newLimit)); } public Flux<MessageId> listMailboxContentSinceAfterSortedBySentAt(PostgresMailboxId mailboxId, ZonedDateTime since, Limit limit, boolean collapseThreads) { @@ -126,12 +118,8 @@ public class PostgresEmailQueryViewDAO { .limit(backendFetchLimit.getLimit().get()))) .map(asEmailEntry(SENT_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSinceAfterSortedBySentAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSinceAfterSortedBySentAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); } public Flux<MessageId> listMailboxContentSinceAfterSortedByReceivedAt(PostgresMailboxId mailboxId, ZonedDateTime since, Limit limit, boolean collapseThreads) { @@ -151,12 +139,8 @@ public class PostgresEmailQueryViewDAO { .limit(backendFetchLimit.getLimit().get()))) .map(asEmailEntry(RECEIVED_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSinceAfterSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSinceAfterSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); } public Flux<MessageId> listMailboxContentBeforeSortedByReceivedAt(PostgresMailboxId mailboxId, ZonedDateTime since, Limit limit, boolean collapseThreads) { @@ -176,12 +160,8 @@ public class PostgresEmailQueryViewDAO { .limit(backendFetchLimit.getLimit().get()))) .map(asEmailEntry(RECEIVED_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentBeforeSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentBeforeSortedByReceivedAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); } public Flux<MessageId> listMailboxContentSinceSentAt(PostgresMailboxId mailboxId, ZonedDateTime since, Limit limit, boolean collapseThreads) { @@ -201,12 +181,8 @@ public class PostgresEmailQueryViewDAO { .limit(backendFetchLimit.getLimit().get()))) .map(asEmailEntry(SENT_AT)); - if (collapseThreads) { - return messagesWithCollapseThreads(limit, backendFetchLimit, baseEntries, - newLimit -> listMailboxContentSinceSentAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); - } - - return baseEntries.map(EmailEntry::getMessageId); + return messagesWithMaybeCollapseThreads(limit, backendFetchLimit, baseEntries, collapseThreads, + newLimit -> listMailboxContentSinceSentAtWithBackendLimit(mailboxId, since, limit, collapseThreads, newLimit)); } private Function<Record, EmailEntry> asEmailEntry(Field<OffsetDateTime> dateField) { diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryViewUtils.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryViewUtils.java index 42f8ee454f..f604ce68f5 100644 --- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryViewUtils.java +++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/projections/EmailQueryViewUtils.java @@ -100,6 +100,25 @@ public class EmailQueryViewUtils { }); } + public static Flux<MessageId> messagesWithMaybeCollapseThreads(Limit limit, Limit backendFetchLimit, Flux<EmailEntry> baseEntries, boolean collapseThreads, Function<Limit, Flux<MessageId>> listMessagesCallbackFunction) { + if (collapseThreads) { + return baseEntries.collectList() + .flatMapMany(results -> { + List<EmailEntry> distinctByThreadId = distinctByThreadId(results); + boolean hasEnoughResults = distinctByThreadId.size() >= limit.getLimit().get(); + boolean isExhaustive = results.size() < backendFetchLimit.getLimit().get(); + if (hasEnoughResults || isExhaustive) { + return Flux.fromIterable(distinctByThreadId) + .take(limit.getLimit().get()) + .map(EmailEntry::getMessageId); + } + Limit newBackendFetchLimit = Limit.from(backendFetchLimit.getLimit().get() * COLLAPSE_THREADS_LIMIT_MULTIPLIER); + return listMessagesCallbackFunction.apply(newBackendFetchLimit); + }); + } + return baseEntries.map(EmailEntry::getMessageId); + } + private static List<EmailEntry> distinctByThreadId(List<EmailEntry> emailEntries) { ImmutableList.Builder<EmailEntry> list = ImmutableList.builder(); HashSet<ThreadId> threadIdHashSet = new HashSet<>(); 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/EmailQueryMethodContract.scala b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala index f90c310660..8ebaa69b5f 100644 --- a/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala +++ b/server/protocols/jmap-rfc-8621-integration-tests/jmap-rfc-8621-integration-tests-common/src/main/scala/org/apache/james/jmap/rfc8621/contract/EmailQueryMethodContract.scala @@ -7472,26 +7472,9 @@ trait EmailQueryMethodContract { @Test def inMailboxAfterSortedByReceivedAtShouldCollapseThreads(server: GuiceJamesServer): Unit = { - val message1: Message = Message.Builder - .of - .setSubject("test") - .setMessageId("Message-ID") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message2: Message = Message.Builder - .of - .setSubject("BTW") - .setMessageId("Message-ID-2") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message3: Message = Message.Builder - .of - .setSubject("Hello again") - .setMessageId("Message-ID-3") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message1: Message = buildTestThreadMessage("test", "Message-ID") + val message2: Message = buildTestThreadMessage("BTW", "Message-ID-2") + val message3: Message = buildTestThreadMessage("Hello again", "Message-ID-3") val beforeRequestDate1 = Date.from(ZonedDateTime.now().minusDays(3).toInstant) val requestDate = ZonedDateTime.now().minusDays(1) @@ -7500,31 +7483,11 @@ trait EmailQueryMethodContract { val afterRequestDate3 = Date.from(ZonedDateTime.now().plusDays(2).toInstant) val mailboxProbe = server.getProbe(classOf[MailboxProbeImpl]) val mailboxId = mailboxProbe.createMailbox(MailboxPath.inbox(BOB)) - val messageId1: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(beforeRequestDate1) - .build(message1)) - .getMessageId - val messageId2: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(afterRequestDate1) - .build(message2)) - .getMessageId - - val messageId3: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(afterRequestDate2) - .build(message3)) - .getMessageId - - val messageId4: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(afterRequestDate3) - .build(message3)) - .getMessageId + val messageId1: MessageId = sendMessageToBobInbox(server, message1, beforeRequestDate1) + val messageId2: MessageId = sendMessageToBobInbox(server, message2, afterRequestDate1) + val messageId3: MessageId = sendMessageToBobInbox(server, message3, afterRequestDate2) + val messageId4: MessageId = sendMessageToBobInbox(server, message3, afterRequestDate3) val request = s"""{ @@ -7582,19 +7545,8 @@ trait EmailQueryMethodContract { @Test def inMailboxSortedByReceivedAtShouldCollapseThreads(server: GuiceJamesServer): Unit = { - val message1: Message = Message.Builder - .of - .setSubject("test") - .setMessageId("Message-ID") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message2: Message = Message.Builder - .of - .setSubject("BTW") - .setMessageId("Message-ID-2") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message1: Message = buildTestThreadMessage("test", "Message-ID") + val message2: Message = buildTestThreadMessage("BTW", "Message-ID-2") val beforeRequestDate1 = Date.from(ZonedDateTime.now().minusDays(3).toInstant) val beforeRequestDate2 = Date.from(ZonedDateTime.now().minusDays(2).toInstant) @@ -7602,31 +7554,11 @@ trait EmailQueryMethodContract { val afterRequestDate2 = Date.from(ZonedDateTime.now().plusDays(1).toInstant) val mailboxProbe = server.getProbe(classOf[MailboxProbeImpl]) val mailboxId = mailboxProbe.createMailbox(MailboxPath.inbox(BOB)) - val messageId1: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(beforeRequestDate1) - .build(message1)) - .getMessageId - - val messageId2: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(beforeRequestDate2) - .build(message1)) - .getMessageId - val messageId3: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(afterRequestDate1) - .build(message2)) - .getMessageId - - val messageId4: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(afterRequestDate2) - .build(message2)) - .getMessageId + val messageId1: MessageId = sendMessageToBobInbox(server, message1, beforeRequestDate1) + val messageId2: MessageId = sendMessageToBobInbox(server, message1, beforeRequestDate2) + val messageId3: MessageId = sendMessageToBobInbox(server, message2, afterRequestDate1) + val messageId4: MessageId = sendMessageToBobInbox(server, message2, afterRequestDate2) val request = s"""{ @@ -7683,26 +7615,9 @@ trait EmailQueryMethodContract { @Test def inMailboxAfterSortedBySentAtShouldCollapseThreads(server: GuiceJamesServer): Unit = { - val message1: Message = Message.Builder - .of - .setSubject("test") - .setMessageId("Message-ID") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message2: Message = Message.Builder - .of - .setSubject("BTW") - .setMessageId("Message-ID-2") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message3: Message = Message.Builder - .of - .setSubject("Hello again") - .setMessageId("Message-ID-3") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message1: Message = buildTestThreadMessage("test", "Message-ID") + val message2: Message = buildTestThreadMessage("BTW", "Message-ID-2") + val message3: Message = buildTestThreadMessage("Hello again", "Message-ID-3") val beforeRequestDate1 = Date.from(ZonedDateTime.now().minusDays(3).toInstant) val requestDate = ZonedDateTime.now().minusDays(1) @@ -7711,31 +7626,11 @@ trait EmailQueryMethodContract { val afterRequestDate3 = Date.from(ZonedDateTime.now().plusDays(2).toInstant) val mailboxProbe = server.getProbe(classOf[MailboxProbeImpl]) val mailboxId = mailboxProbe.createMailbox(MailboxPath.inbox(BOB)) - val messageId1: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(beforeRequestDate1) - .build(message1)) - .getMessageId - val messageId2: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(afterRequestDate1) - .build(message2)) - .getMessageId - - val messageId3: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(afterRequestDate2) - .build(message3)) - .getMessageId - - val messageId4: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(afterRequestDate3) - .build(message3)) - .getMessageId + val messageId1: MessageId = sendMessageToBobInbox(server, message1, beforeRequestDate1) + val messageId2: MessageId = sendMessageToBobInbox(server, message2, afterRequestDate1) + val messageId3: MessageId = sendMessageToBobInbox(server, message3, afterRequestDate2) + val messageId4: MessageId = sendMessageToBobInbox(server, message3, afterRequestDate3) val request = s"""{ @@ -7793,19 +7688,8 @@ trait EmailQueryMethodContract { @Test def inMailboxSortedBySentAtShouldCollapseThreads(server: GuiceJamesServer): Unit = { - val message1: Message = Message.Builder - .of - .setSubject("test") - .setMessageId("Message-ID") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message2: Message = Message.Builder - .of - .setSubject("BTW") - .setMessageId("Message-ID-2") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message1: Message = buildTestThreadMessage("test", "Message-ID") + val message2: Message = buildTestThreadMessage("BTW", "Message-ID-2") val beforeRequestDate1 = Date.from(ZonedDateTime.now().minusDays(3).toInstant) val beforeRequestDate2 = Date.from(ZonedDateTime.now().minusDays(2).toInstant) @@ -7813,31 +7697,11 @@ trait EmailQueryMethodContract { val afterRequestDate2 = Date.from(ZonedDateTime.now().plusDays(1).toInstant) val mailboxProbe = server.getProbe(classOf[MailboxProbeImpl]) val mailboxId = mailboxProbe.createMailbox(MailboxPath.inbox(BOB)) - val messageId1: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(beforeRequestDate1) - .build(message1)) - .getMessageId - - val messageId2: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(beforeRequestDate2) - .build(message1)) - .getMessageId - val messageId3: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(afterRequestDate1) - .build(message2)) - .getMessageId - - val messageId4: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(afterRequestDate2) - .build(message2)) - .getMessageId + val messageId1: MessageId = sendMessageToBobInbox(server, message1, beforeRequestDate1) + val messageId2: MessageId = sendMessageToBobInbox(server, message1, beforeRequestDate2) + val messageId3: MessageId = sendMessageToBobInbox(server, message2, afterRequestDate1) + val messageId4: MessageId = sendMessageToBobInbox(server, message2, afterRequestDate2) val request = s"""{ @@ -7894,26 +7758,9 @@ trait EmailQueryMethodContract { @Test def inMailboxBeforeSortedByReceivedAtShouldCollapseThreads(server: GuiceJamesServer): Unit = { - val message1: Message = Message.Builder - .of - .setSubject("test") - .setMessageId("Message-ID") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message2: Message = Message.Builder - .of - .setSubject("BTW") - .setMessageId("Message-ID-2") - .setBody("testmail", StandardCharsets.UTF_8) - .build - - val message3: Message = Message.Builder - .of - .setSubject("Hello again") - .setMessageId("Message-ID-3") - .setBody("testmail", StandardCharsets.UTF_8) - .build + val message1: Message = buildTestThreadMessage("test", "Message-ID") + val message2: Message = buildTestThreadMessage("BTW", "Message-ID-2") + val message3: Message = buildTestThreadMessage("Hello again", "Message-ID-3") val beforeRequestDate1 = Date.from(ZonedDateTime.now().minusDays(3).toInstant) val beforeRequestDate2 = Date.from(ZonedDateTime.now().minusDays(2).toInstant) @@ -7922,31 +7769,11 @@ trait EmailQueryMethodContract { val afterRequestDate1 = Date.from(ZonedDateTime.now().plusDays(1).toInstant) val mailboxProbe = server.getProbe(classOf[MailboxProbeImpl]) val mailboxId = mailboxProbe.createMailbox(MailboxPath.inbox(BOB)) - val messageId1: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(beforeRequestDate1) - .build(message1)) - .getMessageId - - val messageId2: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(beforeRequestDate2) - .build(message2)) - .getMessageId - - val messageId3: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), - AppendCommand.builder() - .withInternalDate(beforeRequestDate3) - .build(message2)) - .getMessageId - val messageId4: MessageId = mailboxProbe - .appendMessage(BOB.asString, MailboxPath.inbox(BOB), AppendCommand.builder() - .withInternalDate(afterRequestDate1) - .build(message3)) - .getMessageId + val messageId1: MessageId = sendMessageToBobInbox(server, message1, beforeRequestDate1) + val messageId2: MessageId = sendMessageToBobInbox(server, message2, beforeRequestDate2) + val messageId3: MessageId = sendMessageToBobInbox(server, message2, beforeRequestDate3) + val messageId4: MessageId = sendMessageToBobInbox(server, message3, afterRequestDate1) val request = s"""{ @@ -8009,6 +7836,15 @@ trait EmailQueryMethodContract { .getMessageId } + private def buildTestThreadMessage(subject: String, mimeMessageId: String) = { + Message.Builder + .of + .setMessageId(mimeMessageId) + .setSubject(subject) + .setBody("testmail", StandardCharsets.UTF_8) + .build + } + private def generateQueryState(messages: MessageId*): String = Hashing.murmur3_32_fixed() .hashUnencodedChars(messages.toList.map(_.serialize).mkString(" ")) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
