Files
fusion/packages/dashboard/app/components/__tests__/TaskReviewTab.test.tsx
Fusion 954ae1078d feat(FN-3276): add task review tab with metadata persistence and desktop la
This merge lands three major features and a significant dashboard enhancement. FN-3276 adds a full Review tab to the task detail modal with multi-step lifecycle: review metadata persistence in the task store, new task workflow routes for refresh and same-task revision, and the review tab UI surface

Fusion-Task-Id: FN-3276
2026-05-07 23:21:05 -07:00

89 lines
3.0 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import { TaskReviewTab } from "../TaskReviewTab";
import { makeTask } from "./TaskDetailModal.test-helpers";
const refreshTaskReview = vi.fn();
const reviseTaskReviewItems = vi.fn();
vi.mock("../../api", () => ({
refreshTaskReview,
reviseTaskReviewItems,
}));
describe("TaskReviewTab", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("renders empty state when review is missing", () => {
render(<TaskReviewTab task={makeTask({ review: undefined })} addToast={vi.fn()} />);
expect(screen.getByText("No review items yet.")).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Request revision" })).toBeDisabled();
});
it("calls refresh endpoint", async () => {
const task = makeTask({ review: { mode: "direct", source: "reviewer-agent", decision: "pending", items: [] } });
refreshTaskReview.mockResolvedValue({ review: task.review, automationStatus: null });
render(<TaskReviewTab task={task} addToast={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: "Refresh" }));
expect(refreshTaskReview).toHaveBeenCalledWith(task.id, undefined);
});
it("renders PR decision and status modifiers", () => {
const task = makeTask({
review: {
mode: "pull-request",
source: "github-pr",
decision: "changes-requested",
summary: "Needs updates",
items: [
{
id: "ri-1",
source: "github-pr",
status: "failed",
summary: "Fix null handling",
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
},
],
},
});
render(<TaskReviewTab task={task} addToast={vi.fn()} />);
expect(screen.getByText("changes requested")).toBeInTheDocument();
expect(screen.getByText("failed").className).toContain("task-review-tab__status--failed");
});
it("renders review items and queues revision for selected entries", async () => {
const task = makeTask({
review: {
mode: "pull-request",
source: "github-pr",
decision: "changes-requested",
summary: "Needs updates",
items: [
{
id: "ri-1",
source: "github-pr",
status: "queued",
summary: "Fix null handling",
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
},
],
},
});
reviseTaskReviewItems.mockResolvedValue({ task, review: task.review });
refreshTaskReview.mockResolvedValue({ review: task.review, automationStatus: null });
render(<TaskReviewTab task={task} addToast={vi.fn()} />);
fireEvent.click(screen.getByRole("checkbox"));
fireEvent.click(screen.getByRole("button", { name: "Request revision" }));
expect(reviseTaskReviewItems).toHaveBeenCalledWith(task.id, ["ri-1"], undefined);
});
});