






















@@ -122,6 +122,48 @@ function requireCapturedItemEventHandler() {
122122return handler;
123123}
124124125+function requireRecord(value: unknown, label: string): Record<string, unknown> {
126+expect(typeof value).toBe("object");
127+expect(value).not.toBeNull();
128+if (typeof value !== "object" || value === null) {
129+throw new Error(`${label} was not an object`);
130+}
131+return value as Record<string, unknown>;
132+}
133+134+function expectRecordFields(record: Record<string, unknown>, fields: Record<string, unknown>) {
135+for (const [key, value] of Object.entries(fields)) {
136+expect(record[key]).toEqual(value);
137+}
138+}
139+140+function requireMockCall(mock: unknown, index: number, label: string): unknown[] {
141+const call = (mock as { mock?: { calls?: unknown[][] } }).mock?.calls?.[index];
142+expect(call).toBeDefined();
143+if (!call) {
144+throw new Error(`missing ${label} call ${index + 1}`);
145+}
146+return call;
147+}
148+149+function expectMockCallArgFields(
150+mock: unknown,
151+index: number,
152+label: string,
153+fields: Record<string, unknown>,
154+) {
155+expectRecordFields(requireRecord(requireMockCall(mock, index, label)[0], label), fields);
156+}
157+158+function expectDeliverReplyCall(index: number, text: string, fields?: Record<string, unknown>) {
159+const params = requireRecord(
160+requireMockCall(deliverRepliesMock, index, "deliver replies")[0],
161+"deliver replies params",
162+);
163+expectRecordFields(params, { replyThreadTs: THREAD_TS, ...fields });
164+expect(params.replies).toEqual([{ text }]);
165+}
166+125167const noop = () => {};
126168const noopAsync = async () => {};
127169@@ -696,12 +738,7 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
696738697739expect(finalizeSlackPreviewEditMock).toHaveBeenCalledTimes(1);
698740expect(deliverRepliesMock).toHaveBeenCalledTimes(1);
699-expect(deliverRepliesMock).toHaveBeenCalledWith(
700-expect.objectContaining({
701-replyThreadTs: THREAD_TS,
702-replies: [expect.objectContaining({ text: FINAL_REPLY_TEXT })],
703-}),
704-);
741+expectDeliverReplyCall(0, FINAL_REPLY_TEXT);
705742});
706743707744it("finalizes fast draft preview text without sending a duplicate normal reply", async () => {
@@ -720,13 +757,11 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
720757721758expect(draftStream.flush).toHaveBeenCalledTimes(1);
722759expect(draftStream.seal).toHaveBeenCalledTimes(1);
723-expect(finalizeSlackPreviewEditMock).toHaveBeenCalledWith(
724-expect.objectContaining({
725-channelId: "C123",
726-messageId: "171234.567",
727-text: "✅",
728-}),
729-);
760+expectMockCallArgFields(finalizeSlackPreviewEditMock, 0, "preview edit params", {
761+channelId: "C123",
762+messageId: "171234.567",
763+text: "✅",
764+});
730765expect(deliverRepliesMock).not.toHaveBeenCalled();
731766expect(draftStream.clear).not.toHaveBeenCalled();
732767});
@@ -767,17 +802,17 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
767802threadTs: THREAD_TS,
768803status: "",
769804});
770-expect(reactSlackMessageMock).toHaveBeenCalledWith(
771- "C123",
772- "171234.111",
773- "hourglass_flowing_sand",
774- expect.objectContaining({ token: "xoxb-test" }),
775-);
776-expect(removeSlackReactionMock).toHaveBeenCalledWith(
777- "C123",
778- "171234.111",
779- "hourglass_flowing_sand",
780-expect.objectContaining({ token: "xoxb-test" }),
805+const reactCall = requireMockCall(reactSlackMessageMock, 0, "react Slack message");
806+expect(reactCall[0]).toBe("C123");
807+expect(reactCall[1]).toBe("171234.111");
808+expect(reactCall[2]).toBe("hourglass_flowing_sand");
809+expect(requireRecord(reactCall[3], "react Slack message options").token).toBe("xoxb-test");
810+const removeReactionCall = requireMockCall(removeSlackReactionMock, 0, "remove Slack reaction");
811+expect(removeReactionCall[0]).toBe("C123");
812+expect(removeReactionCall[1]).toBe("171234.111");
813+expect(removeReactionCall[2]).toBe("hourglass_flowing_sand");
814+expect(requireRecord(removeReactionCall[3], "remove Slack reaction options").token).toBe(
815+"xoxb-test",
781816);
782817});
783818@@ -797,12 +832,10 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
797832);
798833799834expect(capturedReplyOptions?.disableBlockStreaming).toBe(true);
800-expect(capturedStatusReactionOptions).toEqual(
801-expect.objectContaining({
802-enabled: true,
803-initialEmoji: "eyes",
804-}),
805-);
835+expectRecordFields(requireRecord(capturedStatusReactionOptions, "status reaction options"), {
836+enabled: true,
837+initialEmoji: "eyes",
838+});
806839expect(statusReactionControllerMock.setQueued).toHaveBeenCalledTimes(1);
807840expect(statusReactionControllerMock.setDone).toHaveBeenCalledTimes(1);
808841});
@@ -969,13 +1002,11 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
9691002}),
9701003);
9711004972-expect(startSlackStreamMock).toHaveBeenCalledWith(
973-expect.objectContaining({
974-channel: "C123",
975-threadTs: "171234.111",
976-text: FINAL_REPLY_TEXT,
977-}),
978-);
1005+expectMockCallArgFields(startSlackStreamMock, 0, "Slack stream start params", {
1006+channel: "C123",
1007+threadTs: "171234.111",
1008+text: FINAL_REPLY_TEXT,
1009+});
9791010expect(deliverRepliesMock).not.toHaveBeenCalled();
9801011});
9811012@@ -989,11 +1020,9 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
9891020await dispatchPreparedSlackMessage(createPreparedSlackMessage());
99010219911022expect(startSlackStreamMock).toHaveBeenCalledTimes(1);
992-expect(startSlackStreamMock).toHaveBeenCalledWith(
993-expect.objectContaining({
994-text: FINAL_REPLY_TEXT,
995-}),
996-);
1023+expectMockCallArgFields(startSlackStreamMock, 0, "Slack stream start params", {
1024+text: FINAL_REPLY_TEXT,
1025+});
9971026expect(appendSlackStreamMock).not.toHaveBeenCalled();
9981027expect(deliverRepliesMock).not.toHaveBeenCalled();
9991028});
@@ -1008,20 +1037,8 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
1008103710091038expect(finalizeSlackPreviewEditMock).toHaveBeenCalledTimes(1);
10101039expect(deliverRepliesMock).toHaveBeenCalledTimes(2);
1011-expect(deliverRepliesMock).toHaveBeenNthCalledWith(
1012-1,
1013-expect.objectContaining({
1014-replyThreadTs: THREAD_TS,
1015-replies: [expect.objectContaining({ text: SAME_TEXT })],
1016-}),
1017-);
1018-expect(deliverRepliesMock).toHaveBeenNthCalledWith(
1019-2,
1020-expect.objectContaining({
1021-replyThreadTs: THREAD_TS,
1022-replies: [expect.objectContaining({ text: SAME_TEXT })],
1023-}),
1024-);
1040+expectDeliverReplyCall(0, SAME_TEXT);
1041+expectDeliverReplyCall(1, SAME_TEXT);
10251042});
1026104310271044it("keeps multi-part block replies in the first reply thread after the plan is consumed", async () => {
@@ -1038,20 +1055,8 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
10381055);
1039105610401057expect(deliverRepliesMock).toHaveBeenCalledTimes(2);
1041-expect(deliverRepliesMock).toHaveBeenNthCalledWith(
1042-1,
1043-expect.objectContaining({
1044-replyThreadTs: THREAD_TS,
1045-replies: [expect.objectContaining({ text: "first block" })],
1046-}),
1047-);
1048-expect(deliverRepliesMock).toHaveBeenNthCalledWith(
1049-2,
1050-expect.objectContaining({
1051-replyThreadTs: THREAD_TS,
1052-replies: [expect.objectContaining({ text: "second block" })],
1053-}),
1054-);
1058+expectDeliverReplyCall(0, "first block");
1059+expectDeliverReplyCall(1, "second block");
10551060});
1056106110571062it("does not flush draft previews for media finals before normal delivery", async () => {
@@ -1122,12 +1127,7 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
1122112711231128expect(postMessageMock).not.toHaveBeenCalled();
11241129expect(deliverRepliesMock).toHaveBeenCalledTimes(1);
1125-expect(deliverRepliesMock).toHaveBeenCalledWith(
1126-expect.objectContaining({
1127-replyThreadTs: THREAD_TS,
1128-replies: [expect.objectContaining({ text: FINAL_REPLY_TEXT })],
1129-}),
1130-);
1130+expectDeliverReplyCall(0, FINAL_REPLY_TEXT);
11311131expect(session.stopped).toBe(true);
11321132});
11331133@@ -1154,12 +1154,7 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
1154115411551155expect(postMessageMock).not.toHaveBeenCalled();
11561156expect(deliverRepliesMock).toHaveBeenCalledTimes(1);
1157-expect(deliverRepliesMock).toHaveBeenCalledWith(
1158-expect.objectContaining({
1159-replyThreadTs: THREAD_TS,
1160-replies: [expect.objectContaining({ text: "first buffered\nsecond flushes" })],
1161-}),
1162-);
1157+expectDeliverReplyCall(0, "first buffered\nsecond flushes");
11631158expect(stopSlackStreamMock).not.toHaveBeenCalled();
11641159});
11651160@@ -1183,13 +1178,7 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
1183117811841179expect(postMessageMock).not.toHaveBeenCalled();
11851180expect(deliverRepliesMock).toHaveBeenCalledTimes(1);
1186-expect(deliverRepliesMock).toHaveBeenCalledWith(
1187-expect.objectContaining({
1188-replyThreadTs: THREAD_TS,
1189-textLimit: 4000,
1190-replies: [expect.objectContaining({ text: oversized })],
1191-}),
1192-);
1181+expectDeliverReplyCall(0, oversized, { textLimit: 4000 });
11931182expect(session.stopped).toBe(true);
11941183});
11951184@@ -1221,12 +1210,7 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
12211210// Chunked fallback sent the FULL pendingText, not just the failing
12221211// payload (so the earlier buffered chunk is not dropped).
12231212expect(deliverRepliesMock).toHaveBeenCalledTimes(1);
1224-expect(deliverRepliesMock).toHaveBeenCalledWith(
1225-expect.objectContaining({
1226-replyThreadTs: THREAD_TS,
1227-replies: [expect.objectContaining({ text: "first buffered\nsecond payload" })],
1228-}),
1229-);
1213+expectDeliverReplyCall(0, "first buffered\nsecond payload");
12301214// Session was marked fallback-delivered by deliverPendingStreamFallback,
12311215// so finalize skips stopSlackStream.
12321216expect(session.pendingText).toBe("");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。