test: tighten matrix draft stream assertions

This commit is contained in:
Peter Steinberger
2026-05-11 00:41:06 +01:00
parent 32c1ba77b6
commit 56c836e8ba

View File

@@ -171,6 +171,18 @@ function createMockClient() {
} as unknown as import("./sdk.js").MatrixClient;
}
function sentContentAt(callIndex: number): Record<string, unknown> {
const content = sendMessageMock.mock.calls[callIndex]?.[1];
expect(content).toBeDefined();
expect(typeof content).toBe("object");
expect(content).not.toBeNull();
return content as Record<string, unknown>;
}
function expectLogContaining(log: ReturnType<typeof vi.fn>, fragment: string): void {
expect(log.mock.calls.some((call) => String(call[0]).includes(fragment))).toBe(true);
}
beforeAll(async () => {
const runtimeModule = await import("../runtime.js");
runtimeModule.setMatrixRuntime(runtimeStub);
@@ -207,9 +219,7 @@ describe("createMatrixDraftStream", () => {
await stream.flush();
expect(sendMessageMock).toHaveBeenCalledTimes(1);
expect(sendMessageMock.mock.calls[0]?.[1]).toMatchObject({
msgtype: "m.text",
});
expect(sentContentAt(0).msgtype).toBe("m.text");
expect(stream.eventId()).toBe("$evt1");
});
@@ -225,10 +235,8 @@ describe("createMatrixDraftStream", () => {
await stream.flush();
expect(sendMessageMock).toHaveBeenCalledTimes(1);
expect(sendMessageMock.mock.calls[0]?.[1]).toMatchObject({
msgtype: "m.notice",
});
expect(sendMessageMock.mock.calls[0]?.[1]).not.toHaveProperty("m.mentions");
expect(sentContentAt(0).msgtype).toBe("m.notice");
expect(sentContentAt(0)).not.toHaveProperty("m.mentions");
});
it("edits the message on subsequent quiet updates", async () => {
@@ -251,9 +259,10 @@ describe("createMatrixDraftStream", () => {
// First call = initial send, second call = edit (both go through sendMessage)
expect(sendMessageMock).toHaveBeenCalledTimes(2);
expect(sendMessageMock.mock.calls[1]?.[1]).toMatchObject({
expect(sentContentAt(1).msgtype).toBe("m.notice");
expect(sentContentAt(1)["m.new_content"]).toEqual({
msgtype: "m.notice",
"m.new_content": { msgtype: "m.notice" },
body: "Hello world",
});
});
@@ -273,14 +282,12 @@ describe("createMatrixDraftStream", () => {
// First update fires immediately (fresh throttle window), then AB/ABC
// coalesce into a single edit with the latest text.
expect(sendMessageMock).toHaveBeenCalledTimes(2);
expect(sendMessageMock.mock.calls[0][1]).toMatchObject({ body: "A" });
expect(sentContentAt(0).body).toBe("A");
// Edit uses "* <text>" prefix per Matrix m.replace spec.
expect(sendMessageMock.mock.calls[1][1]).toMatchObject({ body: "* ABC" });
expect(sendMessageMock.mock.calls[0][1]).toMatchObject({ msgtype: "m.notice" });
expect(sendMessageMock.mock.calls[1][1]).toMatchObject({
msgtype: "m.notice",
"m.new_content": { msgtype: "m.notice" },
});
expect(sentContentAt(1).body).toBe("* ABC");
expect(sentContentAt(0).msgtype).toBe("m.notice");
expect(sentContentAt(1).msgtype).toBe("m.notice");
expect(sentContentAt(1)["m.new_content"]).toEqual({ msgtype: "m.notice", body: "ABC" });
});
it("skips no-op updates", async () => {
@@ -417,7 +424,7 @@ describe("createMatrixDraftStream", () => {
await stream.flush();
// Should have logged the failure
expect(log).toHaveBeenCalledWith(expect.stringContaining("send/edit failed"));
expectLogContaining(log, "send/edit failed");
vi.advanceTimersByTime(1000);
@@ -464,7 +471,7 @@ describe("createMatrixDraftStream", () => {
stream.update("Hello world");
await stream.flush();
expect(log).toHaveBeenCalledWith(expect.stringContaining("send/edit failed"));
expectLogContaining(log, "send/edit failed");
vi.advanceTimersByTime(1000);
@@ -488,7 +495,7 @@ describe("createMatrixDraftStream", () => {
await stream.flush();
expect(sendMessageMock).toHaveBeenCalledTimes(1);
expect(sendMessageMock.mock.calls[0]?.[1]).toMatchObject({ body: "line 1\nline 2" });
expect(sentContentAt(0).body).toBe("line 1\nline 2");
});
it("falls back to normal delivery when preview text exceeds one Matrix event", async () => {
@@ -506,9 +513,7 @@ describe("createMatrixDraftStream", () => {
expect(sendMessageMock).not.toHaveBeenCalled();
expect(stream.eventId()).toBeUndefined();
expect(log).toHaveBeenCalledWith(
expect.stringContaining("preview exceeded single-event limit"),
);
expectLogContaining(log, "preview exceeded single-event limit");
});
it("discardPending cancels pending updates without creating another preview event", async () => {
@@ -544,8 +549,6 @@ describe("createMatrixDraftStream", () => {
await stream.flush();
expect(sendMessageMock).not.toHaveBeenCalled();
expect(log).toHaveBeenCalledWith(
expect.stringContaining("preview exceeded single-event limit"),
);
expectLogContaining(log, "preview exceeded single-event limit");
});
});