test: tighten synology chat webhook assertions

This commit is contained in:
Shakker
2026-05-10 17:07:26 +01:00
parent 64a4ff41ce
commit f5cbf9358a

View File

@@ -26,6 +26,26 @@ function countMatching<T>(items: readonly T[], predicate: (item: T) => boolean):
return count;
}
function deliveredMessage(deliver: ReturnType<typeof vi.fn>) {
expect(deliver).toHaveBeenCalledTimes(1);
const message = deliver.mock.calls[0]?.[0] as
| {
accountId?: unknown;
body?: unknown;
chatType?: unknown;
chatUserId?: unknown;
commandAuthorized?: unknown;
from?: unknown;
provider?: unknown;
senderName?: unknown;
}
| undefined;
if (!message) {
throw new Error("expected delivered Synology Chat message");
}
return message;
}
function makeAccount(
overrides: Partial<ResolvedSynologyChatAccount> = {},
): ResolvedSynologyChatAccount {
@@ -420,14 +440,14 @@ describe("createWebhookHandler", () => {
await handler(req, res);
expect(res._status).toBe(204);
expect(deliver).toHaveBeenCalledWith(
expect.objectContaining({
body: "Hello from json",
from: "123",
senderName: "json-user",
commandAuthorized: true,
}),
);
const message = deliveredMessage(deliver);
expect(message.body).toBe("Hello from json");
expect(message.from).toBe("123");
expect(message.senderName).toBe("json-user");
expect(message.provider).toBe("synology-chat");
expect(message.chatType).toBe("direct");
expect(message.commandAuthorized).toBe(true);
expect(message.chatUserId).toBe("123");
});
it("accepts token from query when body token is absent", async () => {
@@ -527,33 +547,28 @@ describe("createWebhookHandler", () => {
expect(res._status).toBe(204);
// deliver should have been called with the stripped text
expect(deliver).toHaveBeenCalledWith(expect.objectContaining({ body: "Hello there" }));
expect(deliveredMessage(deliver).body).toBe("Hello there");
});
it("responds 204 immediately and delivers async", async () => {
const { deliver, res } = await runValidReply({ accountIdSuffix: "async-test" });
expect(res._body).toBe("");
expect(deliver).toHaveBeenCalledWith(
expect.objectContaining({
body: "Hello bot",
from: "123",
senderName: "testuser",
provider: "synology-chat",
chatType: "direct",
commandAuthorized: true,
}),
);
const message = deliveredMessage(deliver);
expect(message.body).toBe("Hello bot");
expect(message.from).toBe("123");
expect(message.senderName).toBe("testuser");
expect(message.provider).toBe("synology-chat");
expect(message.chatType).toBe("direct");
expect(message.commandAuthorized).toBe(true);
expect(message.chatUserId).toBe("123");
});
it("keeps replies bound to payload.user_id by default", async () => {
const { deliver } = await runValidReply({ accountIdSuffix: "stable-id-test" });
expect(resolveLegacyWebhookNameToChatUserId).not.toHaveBeenCalled();
expect(deliver).toHaveBeenCalledWith(
expect.objectContaining({
from: "123",
chatUserId: "123",
}),
);
const message = deliveredMessage(deliver);
expect(message.from).toBe("123");
expect(message.chatUserId).toBe("123");
expectBotReplySentTo("123");
});
@@ -562,12 +577,9 @@ describe("createWebhookHandler", () => {
resolvedChatUserId: 456,
accountIdSuffix: "dangerous-name-match-test",
});
expect(deliver).toHaveBeenCalledWith(
expect.objectContaining({
from: "123",
chatUserId: "456",
}),
);
const message = deliveredMessage(deliver);
expect(message.from).toBe("123");
expect(message.chatUserId).toBe("456");
expectBotReplySentTo("456");
});
@@ -578,12 +590,9 @@ describe("createWebhookHandler", () => {
expect(log.warn).toHaveBeenCalledWith(
'Could not resolve Chat API user_id for "testuser" — falling back to webhook user_id 123. Reply delivery may fail.',
);
expect(deliver).toHaveBeenCalledWith(
expect.objectContaining({
from: "123",
chatUserId: "123",
}),
);
const message = deliveredMessage(deliver);
expect(message.from).toBe("123");
expect(message.chatUserId).toBe("123");
expectBotReplySentTo("123");
});
@@ -606,11 +615,8 @@ describe("createWebhookHandler", () => {
const res = makeRes();
await handler(req, res);
expect(deliver).toHaveBeenCalledWith(
expect.objectContaining({
body: expect.stringContaining("[FILTERED]"),
commandAuthorized: true,
}),
);
const message = deliveredMessage(deliver);
expect(String(message.body)).toContain("[FILTERED]");
expect(message.commandAuthorized).toBe(true);
});
});