git » sdk » commit 78aaef9

Get last page when getMessagesBefore(null)

author Stephen Paul Weber
2026-04-19 21:23:46 UTC
committer Stephen Paul Weber
2026-04-19 21:23:46 UTC
parent df8340f7befa78e046079eb912a40e2f4b326a07

Get last page when getMessagesBefore(null)

borogove/Chat.hx +2 -2
test/TestAll.hx +1 -0
test/TestChat.hx +214 -0

diff --git a/borogove/Chat.hx b/borogove/Chat.hx
index 3c14276..98e81a7 100644
--- a/borogove/Chat.hx
+++ b/borogove/Chat.hx
@@ -1001,7 +1001,7 @@ class DirectChat extends Chat {
 				Promise.resolve(messages);
 			} else {
 				var filter:MAMQueryParams = { with: this.chatId };
-				if (before?.serverId != null) filter.page = { before: before.serverId };
+				filter.page = { before: before?.serverId ?? "" };
 				var sync = new MessageSync(this.client, this.stream, filter, null, before?.sortId);
 				fetchFromSync(sync);
 			}
@@ -1707,7 +1707,7 @@ trace("XYZZY no MUC avatar locally matching so fetch vcard", chatId, avatarSha1H
 				Promise.resolve(messages);
 			} else {
 				var filter:MAMQueryParams = {};
-				if (before?.serverId != null) filter.page = { before: before.serverId };
+				filter.page = { before: before?.serverId ?? "" };
 				var sync = new MessageSync(this.client, this.stream, filter, null, before?.sortId, chatId);
 				sync.addContext((builder, stanza) -> {
 					builder = prepareIncomingMessage(builder, stanza);
diff --git a/test/TestAll.hx b/test/TestAll.hx
index 6eb702e..e65fc0c 100644
--- a/test/TestAll.hx
+++ b/test/TestAll.hx
@@ -20,6 +20,7 @@ class TestAll {
 			new TestReaction(),
 			new TestSortId(),
 			new TestHtml(),
+			new TestChat(),
 		]);
 	}
 }
diff --git a/test/TestChat.hx b/test/TestChat.hx
new file mode 100644
index 0000000..b3c316e
--- /dev/null
+++ b/test/TestChat.hx
@@ -0,0 +1,214 @@
+package test;
+
+import utest.Assert;
+import utest.Async;
+import borogove.Client;
+import borogove.ChatMessageBuilder;
+import borogove.Stanza;
+import borogove.JID;
+import borogove.persistence.Dummy;
+
+@:access(borogove)
+class TestChat extends utest.Test {
+	public function testGetMessagesBeforeNull(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = client.getDirectChat("friend@example.com");
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				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");
+				Assert.notNull(before, "before element should be present");
+				Assert.equals("", before.getText());
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesBefore(null);
+	}
+
+	public function testGetMessagesBefore(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = client.getDirectChat("friend@example.com");
+		final builder = new ChatMessageBuilder();
+		builder.serverId = "msg123";
+		builder.direction = MessageSent;
+		builder.recipients = [JID.parse("friend@example.com")];
+		builder.to = JID.parse("friend@example.com");
+		builder.from = JID.parse("test@example.com");
+		builder.senderId = "test@example.com";
+		final message = builder.build();
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				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");
+				Assert.notNull(before, "before element should be present");
+				Assert.equals("msg123", before.getText());
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesBefore(message);
+	}
+
+	public function testGetMessagesAfterNull(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = client.getDirectChat("friend@example.com");
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				final rsm = stanza.findChild("{urn:xmpp:mam:2}query/{http://jabber.org/protocol/rsm}set");
+				Assert.isNull(rsm, "RSM set should NOT be present");
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesAfter(null);
+	}
+
+	public function testGetMessagesAfter(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = client.getDirectChat("friend@example.com");
+		final builder = new ChatMessageBuilder();
+		builder.serverId = "msg456";
+		builder.direction = MessageSent;
+		builder.recipients = [JID.parse("friend@example.com")];
+		builder.to = JID.parse("friend@example.com");
+		builder.from = JID.parse("test@example.com");
+		builder.senderId = "test@example.com";
+		final message = builder.build();
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				final rsm = stanza.findChild("{urn:xmpp:mam:2}query/{http://jabber.org/protocol/rsm}set");
+				Assert.notNull(rsm, "RSM set should be present");
+				final after = rsm.getChild("after");
+				Assert.notNull(after, "after element should be present");
+				Assert.equals("msg456", after.getText());
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesAfter(message);
+	}
+
+	public function testGetMessagesBeforeNullChannel(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = new borogove.Chat.Channel(client, client.stream, persistence, "channel@example.com");
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				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");
+				Assert.notNull(before, "before element should be present");
+				Assert.equals("", before.getText());
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesBefore(null);
+	}
+
+	public function testGetMessagesBeforeChannel(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = new borogove.Chat.Channel(client, client.stream, persistence, "channel@example.com");
+		final builder = new ChatMessageBuilder();
+		builder.serverId = "cmsg123";
+		builder.direction = MessageSent;
+		builder.recipients = [JID.parse("channel@example.com")];
+		builder.to = JID.parse("channel@example.com");
+		builder.from = JID.parse("test@example.com/res");
+		builder.senderId = "test@example.com/res";
+		final message = builder.build();
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				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");
+				Assert.notNull(before, "before element should be present");
+				Assert.equals("cmsg123", before.getText());
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesBefore(message);
+	}
+
+	public function testGetMessagesAfterNullChannel(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = new borogove.Chat.Channel(client, client.stream, persistence, "channel@example.com");
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				final rsm = stanza.findChild("{urn:xmpp:mam:2}query/{http://jabber.org/protocol/rsm}set");
+				Assert.isNull(rsm, "RSM set should NOT be present");
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesAfter(null);
+	}
+
+	public function testGetMessagesAfterChannel(async: Async) {
+		final persistence = new Dummy();
+		final client = new Client("test@example.com", persistence);
+		final chat = new borogove.Chat.Channel(client, client.stream, persistence, "channel@example.com");
+		final builder = new ChatMessageBuilder();
+		builder.serverId = "cmsg456";
+		builder.direction = MessageSent;
+		builder.recipients = [JID.parse("channel@example.com")];
+		builder.to = JID.parse("channel@example.com");
+		builder.from = JID.parse("test@example.com/res");
+		builder.senderId = "test@example.com/res";
+		final message = builder.build();
+
+		client.stream.on("sendStanza", (stanza: Stanza) -> {
+			final query = stanza.findChild("{urn:xmpp:mam:2}query");
+			if (stanza.name == "iq" && query != null) {
+				final rsm = stanza.findChild("{urn:xmpp:mam:2}query/{http://jabber.org/protocol/rsm}set");
+				Assert.notNull(rsm, "RSM set should be present");
+				final after = rsm.getChild("after");
+				Assert.notNull(after, "after element should be present");
+				Assert.equals("cmsg456", after.getText());
+				async.done();
+				return EventHandled;
+			}
+			return EventUnhandled;
+		});
+
+		chat.getMessagesAfter(message);
+	}
+}