test: add unit tests for localStorage persistence and error handling in message channels

This commit is contained in:
Danish Arora 2025-11-26 19:30:36 -05:00
parent d52ea9fd2c
commit d6412e5536
No known key found for this signature in database
GPG Key ID: 1C6EF37CDAE1426E
2 changed files with 93 additions and 0 deletions

View File

@ -1259,4 +1259,60 @@ describe("MessageChannel", function () {
expect(channelB["lamportTimestamp"]).to.equal(timestampBefore);
});
});
describe("Default localStorage persistence", () => {
it("should restore messages from localStorage on channel recreation", async () => {
const persistentChannelId = "persistent-channel";
const channel1 = new MessageChannel(persistentChannelId, "alice");
await sendMessage(channel1, utf8ToBytes("msg-1"), callback);
await sendMessage(channel1, utf8ToBytes("msg-2"), callback);
expect(channel1["localHistory"].length).to.equal(2);
// Recreate channel with same storage - should load history
const channel2 = new MessageChannel(persistentChannelId, "alice");
expect(channel2["localHistory"].length).to.equal(2);
expect(
channel2["localHistory"].slice(0).map((m) => m.messageId)
).to.deep.equal([
MessageChannel.getMessageId(utf8ToBytes("msg-1")),
MessageChannel.getMessageId(utf8ToBytes("msg-2"))
]);
});
it("should include persisted messages in causal history after restart", async () => {
const persistentChannelId = "persistent-causal";
const channel1 = new MessageChannel(persistentChannelId, "alice", {
causalHistorySize: 2
});
await sendMessage(channel1, utf8ToBytes("msg-1"), callback);
await sendMessage(channel1, utf8ToBytes("msg-2"), callback);
await sendMessage(channel1, utf8ToBytes("msg-3"), callback);
const channel2 = new MessageChannel(persistentChannelId, "alice", {
causalHistorySize: 2
});
let capturedMessage: ContentMessage | null = null;
await sendMessage(channel2, utf8ToBytes("msg-4"), async (message) => {
capturedMessage = message;
return { success: true };
});
expect(capturedMessage).to.not.be.null;
expect(capturedMessage!.causalHistory).to.have.lengthOf(2);
// Should reference the last 2 messages (msg-2 and msg-3)
expect(capturedMessage!.causalHistory[0].messageId).to.equal(
MessageChannel.getMessageId(utf8ToBytes("msg-2"))
);
expect(capturedMessage!.causalHistory[1].messageId).to.equal(
MessageChannel.getMessageId(utf8ToBytes("msg-3"))
);
});
});
});

View File

@ -59,4 +59,41 @@ describe("PersistentHistory", () => {
expect(history.length).to.equal(1);
expect(history.slice(0)[0].messageId).to.equal("msg-3");
});
it("handles corrupt data in storage gracefully", () => {
const storage = new MemoryStorage();
storage.setItem("waku:sds:history:channel-1", "{ invalid json }");
const history = new PersistentHistory({ channelId, storage });
expect(history.length).to.equal(0);
// Local history should be empty
expect(storage.getItem("waku:sds:history:channel-1")).to.equal(null);
});
it("isolates history by channel ID", () => {
const storage = new MemoryStorage();
const history1 = new PersistentHistory({
channelId: "channel-1",
storage
});
const history2 = new PersistentHistory({
channelId: "channel-2",
storage
});
history1.push(createMessage("msg-1", 1));
history2.push(createMessage("msg-2", 2));
// Each channel should only see its own messages
expect(history1.length).to.equal(1);
expect(history1.slice(0)[0].messageId).to.equal("msg-1");
expect(history2.length).to.equal(1);
expect(history2.slice(0)[0].messageId).to.equal("msg-2");
expect(storage.getItem("waku:sds:history:channel-1")).to.not.be.null;
expect(storage.getItem("waku:sds:history:channel-2")).to.not.be.null;
});
});