| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-04-22 16:15:41 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2026-04-22 16:15:41 UTC |
| parent | bdf23dec43f75464f479e95efe998fd988c2a906 |
| borogove/MessageSync.hx | +5 | -1 |
| test/TestSortId.hx | +53 | -0 |
diff --git a/borogove/MessageSync.hx b/borogove/MessageSync.hx index 60bfde8..cc1e5bd 100644 --- a/borogove/MessageSync.hx +++ b/borogove/MessageSync.hx @@ -58,7 +58,11 @@ class MessageSync { final promisedMessages:Array<Promise<Message>> = []; if (lastPage != null) { if (filter.page == null) filter.page = {}; - filter.page.after = lastPage.last; + if (filter.page.before == null) { + filter.page.after = lastPage.last; + } else { + filter.page.before = lastPage.first; + } } var query = new MAMQuery(filter, serviceJID); var previousMessageTime = ""; diff --git a/test/TestSortId.hx b/test/TestSortId.hx index 79746c2..39f58f0 100644 --- a/test/TestSortId.hx +++ b/test/TestSortId.hx @@ -178,6 +178,59 @@ class TestSortId extends utest.Test { ); } + public function testSyncBeforePagingStaysBefore(async: Async) { + final persistence = new Dummy(); + final client = new Client("test@example.com", persistence); + final stream = client.stream; + + var sendCount = 0; + var firstIqId = null; + var secondIqId = null; + + stream.on("sendStanza", (stanza: Stanza) -> { + final query = stanza.findChild("{urn:xmpp:mam:2}query"); + if (stanza.name != "iq" || query == null) return EventUnhandled; + + sendCount++; + final rsm = stanza.findChild("{urn:xmpp:mam:2}query/{http://jabber.org/protocol/rsm}set"); + Assert.notNull(rsm, "RSM set should be present"); + + final before = rsm.getChild("before"); + final after = rsm.getChild("after"); + + if (sendCount == 1) { + firstIqId = stanza.attr.get("id"); + Assert.notNull(before, "first page should use before"); + Assert.equals("", before.getText()); + Assert.isNull(after, "first page should not use after"); + } else if (sendCount == 2) { + secondIqId = stanza.attr.get("id"); + Assert.notNull(before, "second page should still use before"); + Assert.equals("mam-first", before.getText()); + Assert.isNull(after, "second page should not switch to after"); + async.done(); + } + + return EventHandled; + }); + + final sync = new MessageSync(client, stream, { with: "sync@example.com", page: { before: "" } }, null, null); + sync.onMessages((list) -> {}); + + sync.fetchNext(); + + stream.onStanza(new Stanza("iq", { type: "result", id: firstIqId, from: "test@example.com", xmlns: "jabber:client" }) + .tag("fin", { xmlns: "urn:xmpp:mam:2" }) + .tag("set", { xmlns: "http://jabber.org/protocol/rsm" }) + .textTag("first", "mam-first") + .textTag("last", "mam-last") + .up() + .up() + ); + + sync.fetchNext(); + } + public function testMessageChannelPrivateSequence() { final persistence = new Dummy(); final client = new Client("test@example.com", persistence);