test(FN-4378): cover tracked delete action prompts in task surfaces
Fusion-Task-Id: FN-4378 Fusion-Task-Lineage: d3867ba8-f852-41e3-9db0-584c0ffc23b1
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { afterEach, describe, it, expect, vi } from "vitest";
|
||||
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
|
||||
import { TaskCard, formatElapsedDurationDone, __test_areTaskCardPropsEqual } from "../TaskCard";
|
||||
import type { ConfirmOptions } from "../../hooks/useConfirm";
|
||||
import type { Task } from "@fusion/core";
|
||||
|
||||
// Mock lucide-react to avoid SVG rendering issues in test env
|
||||
@@ -38,6 +39,11 @@ vi.mock("../../api", () => ({
|
||||
fetchAgent: vi.fn(),
|
||||
}));
|
||||
|
||||
const mockConfirm = vi.fn<(options: ConfirmOptions) => Promise<boolean>>();
|
||||
vi.mock("../../hooks/useConfirm", () => ({
|
||||
useConfirm: () => ({ confirm: mockConfirm }),
|
||||
}));
|
||||
|
||||
import { uploadAttachment, fetchMission, fetchAgent } from "../../api";
|
||||
import { loadAllAppCss, loadAllAppCssBaseOnly } from "../../test/cssFixture";
|
||||
|
||||
@@ -87,6 +93,50 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("TaskCard", () => {
|
||||
it("uses githubIssueAction for tracked task delete", async () => {
|
||||
const onDeleteTask = vi.fn(async () => makeTask());
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(true);
|
||||
|
||||
render(
|
||||
<TaskCard
|
||||
task={makeTask({
|
||||
column: "triage",
|
||||
githubTracking: {
|
||||
enabled: true,
|
||||
issue: { owner: "owner", repo: "repo", number: 42, url: "https://github.com/owner/repo/issues/42", createdAt: "2026-01-01T00:00:00Z" },
|
||||
},
|
||||
} as any)}
|
||||
onOpenDetail={noop}
|
||||
addToast={noop}
|
||||
onDeleteTask={onDeleteTask}
|
||||
/>,
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByLabelText("Delete task"));
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onDeleteTask).toHaveBeenCalledWith("FN-001", { githubIssueAction: "close" });
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps legacy delete options for untracked task", async () => {
|
||||
const onDeleteTask = vi.fn(async () => makeTask());
|
||||
mockConfirm.mockResolvedValueOnce(true);
|
||||
|
||||
render(<TaskCard task={makeTask({ column: "triage" })} onOpenDetail={noop} addToast={noop} onDeleteTask={onDeleteTask} />);
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByLabelText("Delete task"));
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onDeleteTask).toHaveBeenCalledWith("FN-001");
|
||||
});
|
||||
});
|
||||
it("renders the card ID text", () => {
|
||||
render(<TaskCard task={makeTask()} onOpenDetail={noop} addToast={noop} />);
|
||||
expect(screen.getByText("FN-001")).toBeDefined();
|
||||
|
||||
@@ -90,6 +90,68 @@ describe("TaskDetailModal", () => {
|
||||
expect(screen.getByRole("menuitem", { name: "Pause" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("passes githubIssueAction for tracked tasks", async () => {
|
||||
const onDeleteTask = vi.fn().mockResolvedValue({} as Task);
|
||||
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(true);
|
||||
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask({
|
||||
githubTracking: {
|
||||
enabled: true,
|
||||
issue: {
|
||||
owner: "owner",
|
||||
repo: "repo",
|
||||
number: 42,
|
||||
url: "https://github.com/owner/repo/issues/42",
|
||||
createdAt: "2026-01-01T00:00:00.000Z",
|
||||
},
|
||||
},
|
||||
})}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={onDeleteTask}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: /actions/i }));
|
||||
fireEvent.click(screen.getByRole("menuitem", { name: "Delete" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onDeleteTask).toHaveBeenCalledWith("FN-099", { githubIssueAction: "close" });
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps legacy delete payload for untracked tasks", async () => {
|
||||
const onDeleteTask = vi.fn().mockResolvedValue({} as Task);
|
||||
mockConfirm.mockResolvedValueOnce(true);
|
||||
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask()}
|
||||
onClose={noop}
|
||||
onMoveTask={noopMove}
|
||||
onDeleteTask={onDeleteTask}
|
||||
onMergeTask={noopMerge}
|
||||
onOpenDetail={noopOpenDetail}
|
||||
addToast={noop}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: /actions/i }));
|
||||
fireEvent.click(screen.getByRole("menuitem", { name: "Delete" }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onDeleteTask).toHaveBeenCalledWith("FN-099");
|
||||
});
|
||||
});
|
||||
|
||||
it("prompts for dependency-removal confirmation and retries delete with explicit flag", async () => {
|
||||
const onDeleteTask = vi.fn();
|
||||
const conflict = new Error("Cannot delete task FN-099: still referenced as a dependency by FN-100, FN-101.") as Error & {
|
||||
|
||||
Reference in New Issue
Block a user