refactor(slack): dedupe app mention in-flight race setup

This commit is contained in:
Peter Steinberger
2026-03-07 16:51:56 +00:00
parent d33efeef10
commit 949beca0c2

View File

@@ -84,6 +84,38 @@ function createSlackEvent(params: { type: "message" | "app_mention"; ts: string;
return { type: params.type, channel: "C1", ts: params.ts, text: params.text } as never;
}
async function sendMessageEvent(handler: ReturnType<typeof createTestHandler>, ts: string) {
await handler(createSlackEvent({ type: "message", ts, text: "hello" }), { source: "message" });
}
async function sendMentionEvent(handler: ReturnType<typeof createTestHandler>, ts: string) {
await handler(createSlackEvent({ type: "app_mention", ts, text: "<@U_BOT> hello" }), {
source: "app_mention",
wasMentioned: true,
});
}
async function createInFlightMessageScenario(ts: string) {
let resolveMessagePrepare: ((value: unknown) => void) | undefined;
const messagePrepare = new Promise<unknown>((resolve) => {
resolveMessagePrepare = resolve;
});
prepareSlackMessageMock.mockImplementation(async ({ opts }) => {
if (opts.source === "message") {
return messagePrepare;
}
return { ctxPayload: {} };
});
const handler = createTestHandler();
const messagePending = handler(createSlackEvent({ type: "message", ts, text: "hello" }), {
source: "message",
});
await Promise.resolve();
return { handler, messagePending, resolveMessagePrepare };
}
describe("createSlackMessageHandler app_mention race handling", () => {
beforeEach(() => {
prepareSlackMessageMock.mockReset();
@@ -100,103 +132,34 @@ describe("createSlackMessageHandler app_mention race handling", () => {
const handler = createTestHandler();
await handler(createSlackEvent({ type: "message", ts: "1700000000.000100", text: "hello" }), {
source: "message",
});
await handler(
createSlackEvent({
type: "app_mention",
ts: "1700000000.000100",
text: "<@U_BOT> hello",
}),
{ source: "app_mention", wasMentioned: true },
);
await handler(
createSlackEvent({
type: "app_mention",
ts: "1700000000.000100",
text: "<@U_BOT> hello",
}),
{ source: "app_mention", wasMentioned: true },
);
await sendMessageEvent(handler, "1700000000.000100");
await sendMentionEvent(handler, "1700000000.000100");
await sendMentionEvent(handler, "1700000000.000100");
expect(prepareSlackMessageMock).toHaveBeenCalledTimes(2);
expect(dispatchPreparedSlackMessageMock).toHaveBeenCalledTimes(1);
});
it("allows app_mention while message handling is still in-flight, then keeps later duplicates deduped", async () => {
let resolveMessagePrepare: ((value: unknown) => void) | undefined;
const messagePrepare = new Promise<unknown>((resolve) => {
resolveMessagePrepare = resolve;
});
prepareSlackMessageMock.mockImplementation(async ({ opts }) => {
if (opts.source === "message") {
return messagePrepare;
}
return { ctxPayload: {} };
});
const { handler, messagePending, resolveMessagePrepare } =
await createInFlightMessageScenario("1700000000.000150");
const handler = createTestHandler();
const messagePending = handler(
createSlackEvent({ type: "message", ts: "1700000000.000150", text: "hello" }),
{ source: "message" },
);
await Promise.resolve();
await handler(
createSlackEvent({
type: "app_mention",
ts: "1700000000.000150",
text: "<@U_BOT> hello",
}),
{ source: "app_mention", wasMentioned: true },
);
await sendMentionEvent(handler, "1700000000.000150");
resolveMessagePrepare?.(null);
await messagePending;
await handler(
createSlackEvent({
type: "app_mention",
ts: "1700000000.000150",
text: "<@U_BOT> hello",
}),
{ source: "app_mention", wasMentioned: true },
);
await sendMentionEvent(handler, "1700000000.000150");
expect(prepareSlackMessageMock).toHaveBeenCalledTimes(2);
expect(dispatchPreparedSlackMessageMock).toHaveBeenCalledTimes(1);
});
it("suppresses message dispatch when app_mention already dispatched during in-flight race", async () => {
let resolveMessagePrepare: ((value: unknown) => void) | undefined;
const messagePrepare = new Promise<unknown>((resolve) => {
resolveMessagePrepare = resolve;
});
prepareSlackMessageMock.mockImplementation(async ({ opts }) => {
if (opts.source === "message") {
return messagePrepare;
}
return { ctxPayload: {} };
});
const { handler, messagePending, resolveMessagePrepare } =
await createInFlightMessageScenario("1700000000.000175");
const handler = createTestHandler();
const messagePending = handler(
createSlackEvent({ type: "message", ts: "1700000000.000175", text: "hello" }),
{ source: "message" },
);
await Promise.resolve();
await handler(
createSlackEvent({
type: "app_mention",
ts: "1700000000.000175",
text: "<@U_BOT> hello",
}),
{ source: "app_mention", wasMentioned: true },
);
await sendMentionEvent(handler, "1700000000.000175");
resolveMessagePrepare?.({ ctxPayload: {} });
await messagePending;
@@ -210,17 +173,8 @@ describe("createSlackMessageHandler app_mention race handling", () => {
const handler = createTestHandler();
await handler(createSlackEvent({ type: "message", ts: "1700000000.000200", text: "hello" }), {
source: "message",
});
await handler(
createSlackEvent({
type: "app_mention",
ts: "1700000000.000200",
text: "<@U_BOT> hello",
}),
{ source: "app_mention", wasMentioned: true },
);
await sendMessageEvent(handler, "1700000000.000200");
await sendMentionEvent(handler, "1700000000.000200");
expect(prepareSlackMessageMock).toHaveBeenCalledTimes(1);
expect(dispatchPreparedSlackMessageMock).toHaveBeenCalledTimes(1);