test(FN-4429): complete Step 4 — add executor user-cancel regression coverage

Fusion-Task-Id: FN-4429
Fusion-Task-Lineage: b010437b-0e58-43f6-81b3-40dcebbf0873
This commit is contained in:
Fusion
2026-05-14 09:43:57 -07:00
committed by gsxdsm
parent 45ec637b89
commit 5e5078d052

View File

@@ -0,0 +1,96 @@
import { describe, it, expect, vi } from "vitest";
import "./executor-test-helpers.js";
import { TaskExecutor } from "../executor.js";
import { createMockStore, resetExecutorMocks } from "./executor-test-helpers.js";
describe("TaskExecutor user cancel handling", () => {
it("aborts before dispose when user moves in-progress task back to todo", async () => {
resetExecutorMocks();
const store = createMockStore();
const executor = new TaskExecutor(store as any, "/tmp/test");
const callOrder: string[] = [];
const session = {
prompt: vi.fn(),
abort: vi.fn(async () => {
callOrder.push("abort");
}),
dispose: vi.fn(() => {
callOrder.push("dispose");
}),
} as any;
(executor as any).activeSessions.set("FN-001", {
session,
seenSteeringIds: new Set<string>(),
});
(store as any)._trigger("task:moved", {
task: {
id: "FN-001",
column: "todo",
dependencies: [],
steps: [],
currentStep: 0,
log: [],
},
from: "in-progress",
to: "todo",
source: "user",
});
await Promise.resolve();
expect(callOrder[0]).toBe("abort");
expect(callOrder[1]).toBe("dispose");
expect((executor as any).activeSessions.has("FN-001")).toBe(false);
expect((executor as any).userCanceledTaskIds.has("FN-001")).toBe(true);
expect(store.moveTask).not.toHaveBeenCalled();
});
it("does not mark engine-initiated move as user cancel", () => {
resetExecutorMocks();
const store = createMockStore();
const executor = new TaskExecutor(store as any, "/tmp/test");
(store as any)._trigger("task:moved", {
task: {
id: "FN-002",
column: "todo",
dependencies: [],
steps: [],
currentStep: 0,
log: [],
},
from: "in-progress",
to: "todo",
source: "engine",
});
expect((executor as any).userCanceledTaskIds.has("FN-002")).toBe(false);
});
it("clears userCanceled marker when task is moved back to in-progress", () => {
resetExecutorMocks();
const store = createMockStore();
const executor = new TaskExecutor(store as any, "/tmp/test");
(executor as any).userCanceledTaskIds.add("FN-003");
(store as any)._trigger("task:moved", {
task: {
id: "FN-003",
column: "in-progress",
dependencies: [],
steps: [],
currentStep: 0,
log: [],
},
from: "todo",
to: "in-progress",
source: "user",
});
expect((executor as any).userCanceledTaskIds.has("FN-003")).toBe(false);
});
});