fix: distinguish archived automation runs from cancelled ones (#1860)

This commit is contained in:
Clément Fiere
2026-07-24 10:50:36 +02:00
committed by GitHub
parent 93c6987bf5
commit 62919efbdc
12 changed files with 576 additions and 63 deletions
@@ -0,0 +1,76 @@
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { AutomationRun } from "@/lib/types/automation";
const mockUseAutomationRuns = vi.fn();
vi.mock("@/hooks/domains/settings/use-automation-runs", () => ({
useAutomationRuns: (...args: unknown[]) => mockUseAutomationRuns(...args),
}));
const mockPush = vi.fn();
vi.mock("@/lib/routing/client-router", () => ({
useRouter: () => ({ push: mockPush }),
}));
import { RunsSection } from "./runs-section";
function mkRun(overrides: Partial<AutomationRun> = {}): AutomationRun {
return {
id: "run-1",
automation_id: "auto-1",
trigger_id: "trig-1",
trigger_type: "scheduled",
task_id: "task-1",
status: "task_created",
dedup_key: "",
trigger_data: {},
error_message: "",
created_at: new Date().toISOString(),
...overrides,
};
}
function setup(runs: AutomationRun[]) {
mockUseAutomationRuns.mockReturnValue({
runs,
loading: false,
refresh: vi.fn(),
deleteRun: vi.fn(),
deleteAllRuns: vi.fn(),
});
render(<RunsSection automationId="auto-1" executionMode="task" workspaceId="ws-1" />);
// The runs table only renders once the "Recent Runs" disclosure is expanded.
fireEvent.click(screen.getByText(/Recent Runs/));
}
describe("RunsSection status badges", () => {
afterEach(() => {
cleanup();
vi.clearAllMocks();
});
it("labels an archived-task run as Archived, not Cancelled", () => {
setup([mkRun({ id: "run-archived", status: "archived" })]);
expect(screen.getByText("Archived")).toBeTruthy();
expect(screen.queryByText("Cancelled")).toBeNull();
});
it("labels a genuinely cancelled-task run as Cancelled", () => {
setup([mkRun({ id: "run-cancelled", status: "cancelled" })]);
expect(screen.getByText("Cancelled")).toBeTruthy();
expect(screen.queryByText("Archived")).toBeNull();
});
it("distinguishes archived and cancelled runs side by side", () => {
setup([
mkRun({ id: "run-archived", status: "archived" }),
mkRun({ id: "run-cancelled", status: "cancelled" }),
]);
expect(screen.getByText("Archived")).toBeTruthy();
expect(screen.getByText("Cancelled")).toBeTruthy();
});
});
@@ -37,9 +37,14 @@ const STATUS_BADGE: Record<
succeeded: { variant: "default", label: "Succeeded" },
failed: { variant: "destructive", label: "Failed" },
skipped: { variant: "outline", label: "Skipped" },
// The generating task was archived or no longer exists — its outcome is
// unknown, so this is deliberately distinct from succeeded/failed rather
// than guessing one. See internal/automation.RunStatusCancelled.
// The generating task was archived — via the UI or by the agent itself
// (e.g. an "archive this task" instruction). Distinct from a genuine
// user cancellation: archiving just closes the task out, it doesn't
// mean the run's work was rejected. See internal/automation.RunStatusArchived.
archived: { variant: "outline", label: "Archived" },
// The generating task no longer exists, or its current primary session
// is CANCELLED — a real cancellation, distinct from archived.
// See internal/automation.RunStatusCancelled.
cancelled: { variant: "outline", label: "Cancelled" },
};