test(FN-4378): cover delete and leave issue actions in UI flows
Fusion-Task-Id: FN-4378 Fusion-Task-Lineage: d3867ba8-f852-41e3-9db0-584c0ffc23b1
This commit is contained in:
@@ -123,6 +123,106 @@ describe("TaskCard", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("uses githubIssueAction=delete for tracked task delete", async () => {
|
||||
const onDeleteTask = vi.fn(async () => makeTask());
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(false)
|
||||
.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: "delete" });
|
||||
});
|
||||
});
|
||||
|
||||
it("uses githubIssueAction=leave for tracked task delete", async () => {
|
||||
const onDeleteTask = vi.fn(async () => makeTask());
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(false)
|
||||
.mockResolvedValueOnce(false);
|
||||
|
||||
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: "leave" });
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves githubIssueAction on dependency-conflict retry", async () => {
|
||||
const conflict = new Error("Cannot delete task FN-001: still referenced as a dependency by FN-002.") as Error & { status: number; details: { code: string; dependentIds: string[] } };
|
||||
conflict.status = 409;
|
||||
conflict.details = { code: "TASK_HAS_DEPENDENTS", dependentIds: ["FN-002"] };
|
||||
const onDeleteTask = vi.fn()
|
||||
.mockRejectedValueOnce(conflict)
|
||||
.mockResolvedValueOnce(makeTask());
|
||||
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(false)
|
||||
.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).toHaveBeenNthCalledWith(2, "FN-001", { removeDependencyReferences: true, githubIssueAction: "delete" });
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps legacy delete options for untracked task", async () => {
|
||||
const onDeleteTask = vi.fn(async () => makeTask());
|
||||
mockConfirm.mockResolvedValueOnce(true);
|
||||
|
||||
@@ -128,6 +128,60 @@ describe("TaskDetailModal", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("passes githubIssueAction=delete for tracked tasks", async () => {
|
||||
const onDeleteTask = vi.fn().mockResolvedValue({} as Task);
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(false)
|
||||
.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: "delete" });
|
||||
});
|
||||
});
|
||||
|
||||
it("passes githubIssueAction=leave for tracked tasks", async () => {
|
||||
const onDeleteTask = vi.fn().mockResolvedValue({} as Task);
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(false)
|
||||
.mockResolvedValueOnce(false);
|
||||
|
||||
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: "leave" });
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps legacy delete payload for untracked tasks", async () => {
|
||||
const onDeleteTask = vi.fn().mockResolvedValue({} as Task);
|
||||
mockConfirm.mockResolvedValueOnce(true);
|
||||
@@ -165,12 +219,14 @@ describe("TaskDetailModal", () => {
|
||||
.mockResolvedValueOnce({} as Task);
|
||||
|
||||
mockConfirm
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(false)
|
||||
.mockResolvedValueOnce(true)
|
||||
.mockResolvedValueOnce(true);
|
||||
|
||||
render(
|
||||
<TaskDetailModal
|
||||
task={makeTask()}
|
||||
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}
|
||||
@@ -190,6 +246,19 @@ describe("TaskDetailModal", () => {
|
||||
danger: true,
|
||||
});
|
||||
expect(mockConfirm).toHaveBeenNthCalledWith(2, {
|
||||
title: "Linked GitHub Issue",
|
||||
message: "Choose what to do with owner/repo#42 when deleting FN-099.\n\nClose the issue?",
|
||||
confirmLabel: "Close Issue",
|
||||
cancelLabel: "More Options",
|
||||
});
|
||||
expect(mockConfirm).toHaveBeenNthCalledWith(3, {
|
||||
title: "Delete Linked GitHub Issue",
|
||||
message: "Delete owner/repo#42 on GitHub, or leave it unchanged?",
|
||||
confirmLabel: "Delete Issue",
|
||||
cancelLabel: "Leave Unchanged",
|
||||
danger: true,
|
||||
});
|
||||
expect(mockConfirm).toHaveBeenNthCalledWith(4, {
|
||||
title: "Force Delete Task",
|
||||
message: "FN-099 is a dependency of FN-100, FN-101.\n\nDelete anyway by removing these dependency references first?",
|
||||
danger: true,
|
||||
@@ -197,8 +266,11 @@ describe("TaskDetailModal", () => {
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onDeleteTask).toHaveBeenNthCalledWith(1, "FN-099");
|
||||
expect(onDeleteTask).toHaveBeenNthCalledWith(2, "FN-099", { removeDependencyReferences: true });
|
||||
expect(onDeleteTask).toHaveBeenNthCalledWith(1, "FN-099", { githubIssueAction: "delete" });
|
||||
expect(onDeleteTask).toHaveBeenNthCalledWith(2, "FN-099", {
|
||||
removeDependencyReferences: true,
|
||||
githubIssueAction: "delete",
|
||||
});
|
||||
expect(noop).toHaveBeenCalledWith("Deleted FN-099 after removing dependency references", "info");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user