test: dedupe auto-reply delivery mock calls

This commit is contained in:
Peter Steinberger
2026-05-12 13:34:16 +01:00
parent 88714d6803
commit e6551e63ba

View File

@@ -4,6 +4,14 @@ import { HEARTBEAT_TOKEN, SILENT_REPLY_TOKEN } from "../tokens.js";
import { createReplyDispatcher } from "./reply-dispatcher.js";
import { createReplyToModeFilter } from "./reply-threading.js";
type DeliverPayload = Parameters<Parameters<typeof createReplyDispatcher>[0]["deliver"]>[0];
type DeliverMock = { mock: { calls: unknown[][] } };
function deliveredText(deliver: DeliverMock, index = 0) {
const payload = deliver.mock.calls.at(index)?.at(0) as DeliverPayload | undefined;
return payload?.text;
}
describe("createReplyDispatcher", () => {
it("drops empty payloads and exact silent tokens without media", async () => {
const deliver = vi.fn().mockResolvedValue(undefined);
@@ -17,8 +25,8 @@ describe("createReplyDispatcher", () => {
await dispatcher.waitForIdle();
expect(deliver).toHaveBeenCalledTimes(2);
expect(deliver.mock.calls[0]?.[0]?.text).toBe(`${SILENT_REPLY_TOKEN} -- nope`);
expect(deliver.mock.calls[1]?.[0]?.text).toBe(`interject.${SILENT_REPLY_TOKEN}`);
expect(deliveredText(deliver)).toBe(`${SILENT_REPLY_TOKEN} -- nope`);
expect(deliveredText(deliver, 1)).toBe(`interject.${SILENT_REPLY_TOKEN}`);
});
it("rewrites exact NO_REPLY final payloads for direct sessions where rewrite is enabled", async () => {
@@ -50,7 +58,7 @@ describe("createReplyDispatcher", () => {
await dispatcher.waitForIdle();
expect(deliver).toHaveBeenCalledTimes(1);
expect(deliver.mock.calls[0]?.[0]?.text).toBe("No further response from me.");
expect(deliveredText(deliver)).toBe("No further response from me.");
});
it("preserves exact NO_REPLY final payloads for direct sessions where rewrite is disabled", async () => {
@@ -82,7 +90,7 @@ describe("createReplyDispatcher", () => {
await dispatcher.waitForIdle();
expect(deliver).toHaveBeenCalledTimes(1);
expect(deliver.mock.calls[0]?.[0]?.text).toBe(SILENT_REPLY_TOKEN);
expect(deliveredText(deliver)).toBe(SILENT_REPLY_TOKEN);
});
it("still drops exact NO_REPLY final payloads for group sessions where silence is allowed", async () => {
@@ -130,7 +138,7 @@ describe("createReplyDispatcher", () => {
await dispatcher.waitForIdle();
expect(deliver).toHaveBeenCalledTimes(1);
expect(deliver.mock.calls[0][0].text).toBe("PFX hello");
expect(deliveredText(deliver)).toBe("PFX hello");
expect(onHeartbeatStrip).toHaveBeenCalledTimes(2);
});
@@ -163,9 +171,9 @@ describe("createReplyDispatcher", () => {
await dispatcher.waitForIdle();
expect(deliver).toHaveBeenCalledTimes(3);
expect(deliver.mock.calls[0][0].text).toBe("PFX already");
expect(deliver.mock.calls[1][0].text).toBe("");
expect(deliver.mock.calls[2][0].text).toBe(`PFX ${SILENT_REPLY_TOKEN} -- explanation`);
expect(deliveredText(deliver)).toBe("PFX already");
expect(deliveredText(deliver, 1)).toBe("");
expect(deliveredText(deliver, 2)).toBe(`PFX ${SILENT_REPLY_TOKEN} -- explanation`);
});
it("preserves ordering across tool, block, and final replies", async () => {