import { createPinia, setActivePinia } from "pinia"; import { beforeEach, expect, test, vi } from "vitest"; const { casesRequest, startRequest, runRequest, eventsRequest, aggregateRequest } = vi.hoisted(() => ({ casesRequest: vi.fn(), startRequest: vi.fn(), runRequest: vi.fn(), eventsRequest: vi.fn(), aggregateRequest: vi.fn() })); vi.mock("@/api", () => ({ caserunAPI: { cases: casesRequest, startRun: startRequest, run: runRequest, events: eventsRequest, aggregate: aggregateRequest } })); import { useCaseRunStore } from "./caserun"; beforeEach(() => { setActivePinia(createPinia()); casesRequest.mockReset(); startRequest.mockReset(); runRequest.mockReset(); eventsRequest.mockReset(); aggregateRequest.mockReset(); }); test("polling follows API terminal instead of status names", async () => { runRequest.mockResolvedValue({ ok: true, data: { runId: "run-1", caseId: "native-completed", status: "custom-progress", stage: "agent-running", terminal: false } }); eventsRequest.mockResolvedValue({ ok: true, data: { runId: "run-1", events: [] } }); aggregateRequest.mockResolvedValue({ ok: true, data: { runId: "run-1", status: "custom-progress", sha256: "progress-sha" } }); const store = useCaseRunStore(); await store.refreshRun("run-1"); expect(store.shouldPoll).toBe(true); runRequest.mockResolvedValue({ ok: true, data: { runId: "run-1", caseId: "native-completed", status: "running", stage: "completed", terminal: true } }); await store.refreshRun("run-1"); expect(store.shouldPoll).toBe(false); }); test("start keeps blocker and independent aggregate from API read models", async () => { startRequest.mockResolvedValue({ ok: true, data: { runId: "run-2", caseId: "native-blocked", status: "queued", stage: "queued", terminal: false } }); runRequest.mockResolvedValue({ ok: true, data: { runId: "run-2", caseId: "native-blocked", status: "blocked", stage: "preparing", terminal: true, blocker: { code: "native-capability-blocked", summary: "blocked" }, references: { aggregate: { sha256: "embedded-sha" } } } }); eventsRequest.mockResolvedValue({ ok: true, data: { runId: "run-2", events: [{ status: "blocked", stage: "preparing" }] } }); aggregateRequest.mockResolvedValue({ ok: true, data: { mode: "native-test", runId: "run-2", status: "blocked", sha256: "api-aggregate-sha" } }); const store = useCaseRunStore(); await store.startRun("native-blocked"); expect(store.currentRun?.blocker?.code).toBe("native-capability-blocked"); expect(store.aggregate?.runId).toBe("run-2"); expect(store.aggregate?.status).toBe("blocked"); expect(store.aggregate?.sha256).toBe("api-aggregate-sha"); expect(store.shouldPoll).toBe(false); });