mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-23 22:55:24 +00:00
refactor(slack): dedupe app mention in-flight race setup
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user