import React from "react";
import { afterEach, describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { TaskCard, type CliCardState } from "../TaskCard";
import type { Task } from "@fusion/core";
vi.mock("lucide-react", () => {
const Stub = () => null;
return new Proxy({}, {
get: (_target, prop) => prop === "then" ? undefined : Stub,
});
});
vi.mock("../ProviderIcon", () => ({
ProviderIcon: ({ provider }: { provider: string }) => ,
}));
vi.mock("../../hooks/useTaskDiffStats", () => ({
useTaskDiffStats: () => ({ stats: null, loading: false }),
}));
const badgeUpdatesMock = new Map();
vi.mock("../../hooks/useBadgeWebSocket", () => ({
useBadgeWebSocket: () => ({
badgeUpdates: badgeUpdatesMock,
isConnected: true,
subscribeToBadge: vi.fn(),
unsubscribeFromBadge: vi.fn(),
}),
}));
vi.mock("../../hooks/useBatchBadgeFetch", () => ({
getFreshBatchData: vi.fn(() => null),
}));
vi.mock("../../api", () => ({
fetchTaskDetail: vi.fn(),
uploadAttachment: vi.fn(),
fetchMission: vi.fn(),
fetchAgent: vi.fn(),
fetchAgents: vi.fn(),
}));
vi.mock("../../hooks/useConfirm", () => ({
useConfirm: () => ({ confirm: vi.fn(), confirmWithChoice: vi.fn() }),
}));
function makeTask(overrides: Partial = {}): Task {
return {
id: "FN-001",
title: "Test task",
column: "in-progress",
status: undefined as never,
steps: [],
dependencies: [],
description: "",
...overrides,
} as Task;
}
const noop = () => {};
function renderCard(cliSessionState?: CliCardState) {
return render(
,
);
}
afterEach(() => {
badgeUpdatesMock.clear();
vi.clearAllMocks();
});
describe("TaskCard CLI agent state badges (U11)", () => {
it("renders the waiting-on-input badge when the session is waitingOnInput", () => {
renderCard({ agentState: "waitingOnInput" });
const badge = screen.getByText("Waiting on input");
expect(badge).toBeTruthy();
expect(badge.getAttribute("data-cli-state")).toBe("waitingOnInput");
});
it("renders the needs-attention badge when the session needsAttention", () => {
renderCard({ agentState: "needsAttention" });
const badge = screen.getByText("Needs attention");
expect(badge).toBeTruthy();
expect(badge.getAttribute("data-cli-state")).toBe("needsAttention");
});
it("busy clears both CLI badges (F2 — answering re-arms to busy)", () => {
renderCard({ agentState: "busy" });
expect(screen.queryByText("Waiting on input")).toBeNull();
expect(screen.queryByText("Needs attention")).toBeNull();
});
it("no cli session → no CLI badges (card unchanged)", () => {
renderCard(undefined);
expect(screen.queryByText("Waiting on input")).toBeNull();
expect(screen.queryByText("Needs attention")).toBeNull();
});
});