


























@@ -89,6 +89,49 @@ function findMessageWithIdempotencyKey(
8989return undefined;
9090}
919192+function expectRecord(value: unknown, label: string): Record<string, unknown> {
93+expect(typeof value).toBe("object");
94+expect(value, label).not.toBeNull();
95+return value as Record<string, unknown>;
96+}
97+98+function expectAbortPayload(payload: unknown, expected?: { runIds?: string[] }) {
99+const actual = expectRecord(payload, "abort payload");
100+expect(actual.aborted).toBe(true);
101+if (expected?.runIds) {
102+expect(actual.runIds).toEqual(expected.runIds);
103+}
104+return actual;
105+}
106+107+function expectAbortPayloadContainsRunIds(payload: unknown, runIds: string[]) {
108+const actual = expectAbortPayload(payload);
109+expect(Array.isArray(actual.runIds)).toBe(true);
110+for (const runId of runIds) {
111+expect(actual.runIds as unknown[]).toContain(runId);
112+}
113+}
114+115+function expectPersistedAbortMessage(
116+message: unknown,
117+expected: {
118+idempotencyKey: string;
119+origin: string;
120+runId: string;
121+stopReason?: string;
122+},
123+) {
124+const actual = expectRecord(message, "persisted abort message");
125+expect(actual.idempotencyKey).toBe(expected.idempotencyKey);
126+if (expected.stopReason) {
127+expect(actual.stopReason).toBe(expected.stopReason);
128+}
129+const abort = expectRecord(actual.openclawAbort, "persisted abort metadata");
130+expect(abort.aborted).toBe(true);
131+expect(abort.origin).toBe(expected.origin);
132+expect(abort.runId).toBe(expected.runId);
133+}
134+92135function setMockSessionEntry(transcriptPath: string, sessionId: string) {
93136sessionEntryState.transcriptPath = transcriptPath;
94137sessionEntryState.sessionId = sessionId;
@@ -137,7 +180,7 @@ describe("chat abort transcript persistence", () => {
137180138181const [ok1, payload1] = respond.mock.calls.at(-1) ?? [];
139182expect(ok1).toBe(true);
140-expect(payload1).toMatchObject({ aborted: true, runIds: [runId] });
183+expectAbortPayload(payload1, { runIds: [runId] });
141184142185context.chatAbortControllers.set(runId, createActiveRun("main", { sessionId }));
143186context.chatRunBuffers.set(runId, "Partial from run abort");
@@ -154,14 +197,11 @@ describe("chat abort transcript persistence", () => {
154197const persisted = collectMessagesWithIdempotencyKey(lines, `${runId}:assistant`);
155198156199expect(persisted).toHaveLength(1);
157-expect(persisted[0]).toMatchObject({
158-stopReason: "stop",
200+expectPersistedAbortMessage(persisted[0], {
159201idempotencyKey: `${runId}:assistant`,
160-openclawAbort: {
161-aborted: true,
162-origin: "rpc",
163- runId,
164-},
202+origin: "rpc",
203+ runId,
204+stopReason: "stop",
165205});
166206});
167207@@ -194,20 +234,16 @@ describe("chat abort transcript persistence", () => {
194234195235const [ok, payload] = respond.mock.calls.at(-1) ?? [];
196236expect(ok).toBe(true);
197-expect(payload).toMatchObject({ aborted: true });
198-expect(payload.runIds).toEqual(expect.arrayContaining(["run-a", "run-b"]));
237+expectAbortPayloadContainsRunIds(payload, ["run-a", "run-b"]);
199238200239const lines = await readTranscriptLines(transcriptPath);
201240const runAPersisted = findMessageWithIdempotencyKey(lines, "run-a:assistant");
202241const runBPersisted = findMessageWithIdempotencyKey(lines, "run-b:assistant");
203242204-expect(runAPersisted).toMatchObject({
243+expectPersistedAbortMessage(runAPersisted, {
205244idempotencyKey: "run-a:assistant",
206-openclawAbort: {
207-aborted: true,
208-origin: "rpc",
209-runId: "run-a",
210-},
245+origin: "rpc",
246+runId: "run-a",
211247});
212248expect(runBPersisted).toBeUndefined();
213249});
@@ -241,18 +277,15 @@ describe("chat abort transcript persistence", () => {
241277242278const [ok, payload] = respond.mock.calls.at(-1) ?? [];
243279expect(ok).toBe(true);
244-expect(payload).toMatchObject({ aborted: true, runIds: ["run-stop-1"] });
280+expectAbortPayload(payload, { runIds: ["run-stop-1"] });
245281246282const lines = await readTranscriptLines(transcriptPath);
247283const persisted = findMessageWithIdempotencyKey(lines, "run-stop-1:assistant");
248284249-expect(persisted).toMatchObject({
285+expectPersistedAbortMessage(persisted, {
250286idempotencyKey: "run-stop-1:assistant",
251-openclawAbort: {
252-aborted: true,
253-origin: "stop-command",
254-runId: "run-stop-1",
255-},
287+origin: "stop-command",
288+runId: "run-stop-1",
256289});
257290});
258291@@ -277,7 +310,7 @@ describe("chat abort transcript persistence", () => {
277310278311const [ok, payload] = respond.mock.calls.at(-1) ?? [];
279312expect(ok).toBe(true);
280-expect(payload).toMatchObject({ aborted: true, runIds: [runId] });
313+expectAbortPayload(payload, { runIds: [runId] });
281314282315const lines = await readTranscriptLines(transcriptPath);
283316const persisted = findMessageWithIdempotencyKey(lines, `${runId}:assistant`);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。