test(FN-4308): complete Step 4 — add card and modal aggregation regressions

Fusion-Task-Id: FN-4308
Fusion-Task-Lineage: d0a46a8f-2245-4ddc-99b4-06d78e87db16
This commit is contained in:
Fusion
2026-05-13 09:17:13 -07:00
committed by gsxdsm
parent d6504aacea
commit 3a8c19f57a
3 changed files with 67 additions and 3 deletions

View File

@@ -25,6 +25,11 @@ vi.mock("../ProviderIcon", () => ({
ProviderIcon: ({ provider }: { provider: string }) => <span data-testid={`provider-icon-${provider}`} />,
}));
const useTaskDiffStatsMock = vi.fn(() => ({ stats: null, loading: false }));
vi.mock("../../hooks/useTaskDiffStats", () => ({
useTaskDiffStats: (...args: any[]) => useTaskDiffStatsMock(...args),
}));
// Mock the api module
vi.mock("../../api", () => ({
fetchTaskDetail: vi.fn(),
@@ -78,6 +83,7 @@ const highFanout = {
afterEach(() => {
vi.useRealTimers();
useTaskDiffStatsMock.mockReturnValue({ stats: null, loading: false });
});
describe("TaskCard", () => {
@@ -1453,6 +1459,35 @@ describe("TaskCard", () => {
expect(container.querySelector(".card-time-indicator")).not.toBeNull();
});
it("prefers done-task /diff filesChanged over mergeDetails.filesChanged", () => {
useTaskDiffStatsMock.mockReturnValue({
stats: { filesChanged: 4, additions: 10, deletions: 2 },
loading: false,
});
render(
<TaskCard
task={makeTask({
column: "done",
mergeDetails: {
commitSha: "abc123",
filesChanged: 1,
insertions: 10,
deletions: 2,
mergedAt: "2026-04-25T15:00:00.000Z",
mergeConfirmed: true,
},
})}
onOpenDetail={noop}
addToast={noop}
onOpenDetailWithTab={vi.fn()}
/>,
);
expect(screen.getByRole("button", { name: "4 files changed" })).toBeDefined();
expect(screen.queryByRole("button", { name: "1 file changed" })).toBeNull();
});
it("renders files-changed metadata and timer chip in footer row", () => {
const { container } = render(
<TaskCard

View File

@@ -246,6 +246,35 @@ describe("TaskChangesTab — commit-backed (done tasks)", () => {
expect(mockFetchTaskDiff).toHaveBeenCalledWith("FN-001", undefined, undefined);
});
it("renders aggregated done-task file union and matching header count", async () => {
mockFetchTaskDiff.mockResolvedValue({
files: [
{ path: "a.ts", status: "modified", additions: 1, deletions: 0, patch: "@@" },
{ path: "b.ts", status: "added", additions: 2, deletions: 0, patch: "@@" },
{ path: "c.ts", status: "deleted", additions: 0, deletions: 1, patch: "@@" },
{ path: "d.ts", status: "modified", additions: 3, deletions: 2, patch: "@@" },
],
stats: { filesChanged: 4, additions: 6, deletions: 3 },
});
render(
<TaskChangesTab
taskId="FN-001"
worktree={undefined}
column="done"
mergeDetails={MERGE_DETAILS}
/>,
);
await waitFor(() => {
expect(screen.getByText("Files Changed (4)")).toBeTruthy();
});
expect(screen.getByText("a.ts")).toBeTruthy();
expect(screen.getByText("b.ts")).toBeTruthy();
expect(screen.getByText("c.ts")).toBeTruthy();
expect(screen.getByText("d.ts")).toBeTruthy();
});
it("shows commit metadata for done task", async () => {
mockFetchTaskDiff.mockResolvedValue(DONE_TASK_DIFF);