diff --git a/src/tasks/task-executor.test.ts b/src/tasks/task-executor.test.ts index 2be30873a66..2afca1c5e28 100644 --- a/src/tasks/task-executor.test.ts +++ b/src/tasks/task-executor.test.ts @@ -97,6 +97,56 @@ async function withTaskExecutorStateDir(run: (stateDir: string) => Promise }); } +function createRunningAcpChildTaskRun( + overrides: Partial[0]> = {}, +) { + return createRunningTaskRun({ + runtime: "acp", + ownerKey: "agent:main:main", + scopeKind: "session", + childSessionKey: "agent:codex:acp:child", + runId: "run-acp-child", + task: "Inspect a PR", + startedAt: 10, + deliveryStatus: "pending", + ...overrides, + }); +} + +function spyOnRuntimeCancel() { + const defaultRuntime = getDetachedTaskLifecycleRuntime(); + const cancelDetachedTaskRunByIdSpy = vi.fn( + (...args: Parameters) => + defaultRuntime.cancelDetachedTaskRunById(...args), + ); + + setDetachedTaskLifecycleRuntime({ + ...defaultRuntime, + cancelDetachedTaskRunById: cancelDetachedTaskRunByIdSpy, + }); + + return cancelDetachedTaskRunByIdSpy; +} + +function expectCancelledAcpChildTask( + child: ReturnType, + cancelled: unknown, +) { + expect(cancelled).toMatchObject({ + found: true, + cancelled: true, + }); + expect(getTaskById(child.taskId)).toMatchObject({ + taskId: child.taskId, + status: "cancelled", + }); + expect(hoisted.cancelSessionMock).toHaveBeenCalledWith({ + cfg: {} as never, + sessionKey: "agent:codex:acp:child", + reason: "task-cancel", + }); +} + describe("task-executor", () => { afterEach(() => { if (ORIGINAL_STATE_DIR === undefined) { @@ -587,15 +637,8 @@ describe("task-executor", () => { await withTaskExecutorStateDir(async () => { hoisted.cancelSessionMock.mockResolvedValue(undefined); - const child = createRunningTaskRun({ - runtime: "acp", - ownerKey: "agent:main:main", - scopeKind: "session", - childSessionKey: "agent:codex:acp:child", + const child = createRunningAcpChildTaskRun({ runId: "run-linear-cancel", - task: "Inspect a PR", - startedAt: 10, - deliveryStatus: "pending", }); const cancelled = await cancelDetachedTaskRunById({ @@ -603,19 +646,7 @@ describe("task-executor", () => { taskId: child.taskId, }); - expect(cancelled).toMatchObject({ - found: true, - cancelled: true, - }); - expect(getTaskById(child.taskId)).toMatchObject({ - taskId: child.taskId, - status: "cancelled", - }); - expect(hoisted.cancelSessionMock).toHaveBeenCalledWith({ - cfg: {} as never, - sessionKey: "agent:codex:acp:child", - reason: "task-cancel", - }); + expectCancelledAcpChildTask(child, cancelled); }); }); @@ -623,27 +654,11 @@ describe("task-executor", () => { await withTaskExecutorStateDir(async () => { hoisted.cancelSessionMock.mockResolvedValue(undefined); - const child = createRunningTaskRun({ - runtime: "acp", - ownerKey: "agent:main:main", - scopeKind: "session", - childSessionKey: "agent:codex:acp:child", + const child = createRunningAcpChildTaskRun({ runId: "run-external-cancel", - task: "Inspect a PR", - startedAt: 10, - deliveryStatus: "pending", }); - const defaultRuntime = getDetachedTaskLifecycleRuntime(); - const cancelDetachedTaskRunByIdSpy = vi.fn( - (...args: Parameters) => - defaultRuntime.cancelDetachedTaskRunById(...args), - ); - - setDetachedTaskLifecycleRuntime({ - ...defaultRuntime, - cancelDetachedTaskRunById: cancelDetachedTaskRunByIdSpy, - }); + const cancelDetachedTaskRunByIdSpy = spyOnRuntimeCancel(); const cancelled = await cancelDetachedTaskRunById({ cfg: {} as never, @@ -665,15 +680,8 @@ describe("task-executor", () => { await withTaskExecutorStateDir(async () => { hoisted.cancelSessionMock.mockResolvedValue(undefined); - const child = createRunningTaskRun({ - runtime: "acp", - ownerKey: "agent:main:main", - scopeKind: "session", - childSessionKey: "agent:codex:acp:child", + const child = createRunningAcpChildTaskRun({ runId: "run-runtime-decline-cancel", - task: "Inspect a PR", - startedAt: 10, - deliveryStatus: "pending", }); const cancelDetachedTaskRunByIdSpy = vi.fn(async () => ({ @@ -696,19 +704,7 @@ describe("task-executor", () => { cfg: {} as never, taskId: child.taskId, }); - expect(cancelled).toMatchObject({ - found: true, - cancelled: true, - }); - expect(getTaskById(child.taskId)).toMatchObject({ - taskId: child.taskId, - status: "cancelled", - }); - expect(hoisted.cancelSessionMock).toHaveBeenCalledWith({ - cfg: {} as never, - sessionKey: "agent:codex:acp:child", - reason: "task-cancel", - }); + expectCancelledAcpChildTask(child, cancelled); }); }); @@ -716,15 +712,8 @@ describe("task-executor", () => { await withTaskExecutorStateDir(async () => { hoisted.cancelSessionMock.mockResolvedValue(undefined); - const child = createRunningTaskRun({ - runtime: "acp", - ownerKey: "agent:main:main", - scopeKind: "session", - childSessionKey: "agent:codex:acp:child", + const child = createRunningAcpChildTaskRun({ runId: "run-runtime-owned-cancel", - task: "Inspect a PR", - startedAt: 10, - deliveryStatus: "pending", }); const cancelDetachedTaskRunByIdSpy = vi.fn(async () => ({ @@ -824,15 +813,7 @@ describe("task-executor", () => { throw new Error("expected child task payload"); } - const defaultRuntime = getDetachedTaskLifecycleRuntime(); - const cancelDetachedTaskRunByIdSpy = vi.fn( - (...args: Parameters) => - defaultRuntime.cancelDetachedTaskRunById(...args), - ); - setDetachedTaskLifecycleRuntime({ - ...defaultRuntime, - cancelDetachedTaskRunById: cancelDetachedTaskRunByIdSpy, - }); + const cancelDetachedTaskRunByIdSpy = spyOnRuntimeCancel(); const cancelled = await cancelFlowById({ cfg: {} as never,