import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { render, screen, fireEvent } from "@testing-library/react"; import { ChangedFilesModal } from "../ChangedFilesModal"; import * as changedFilesHook from "../../hooks/useChangedFiles"; vi.mock("../../hooks/useChangedFiles"); const mockUseChangedFiles = vi.mocked(changedFilesHook.useChangedFiles); describe("ChangedFilesModal", () => { const mockOnClose = vi.fn(); const mockSetSelectedFile = vi.fn(); beforeEach(() => { vi.resetAllMocks(); mockUseChangedFiles.mockReturnValue({ files: [ { path: "src/a.ts", status: "modified", diff: "diff --git a/src/a.ts b/src/a.ts\n--- a/src/a.ts\n+++ b/src/a.ts\n+hello" }, { path: "src/b.ts", status: "added", diff: "diff --git a/src/b.ts b/src/b.ts" }, ], loading: false, error: null, selectedFile: { path: "src/a.ts", status: "modified", diff: "diff --git a/src/a.ts b/src/a.ts\n--- a/src/a.ts\n+++ b/src/a.ts\n+hello" }, setSelectedFile: mockSetSelectedFile, }); }); afterEach(() => { vi.restoreAllMocks(); }); it("renders changed files and selected diff", () => { render( , ); expect(screen.getByText("Changed Files — KB-651")).toBeInTheDocument(); expect(screen.getByText("src/a.ts")).toBeInTheDocument(); expect(screen.getByLabelText("Diff for src/a.ts")).toBeInTheDocument(); expect(screen.getByText(/\+hello/)).toBeInTheDocument(); }); it("allows selecting another file from the sidebar", () => { render( , ); fireEvent.click(screen.getByRole("button", { name: /src\/b.ts/i })); expect(mockSetSelectedFile).toHaveBeenCalledWith({ path: "src/b.ts", status: "added", diff: "diff --git a/src/b.ts b/src/b.ts" }); }); it("shows an empty state when there are no changed files", () => { mockUseChangedFiles.mockReturnValue({ files: [], loading: false, error: null, selectedFile: null, setSelectedFile: mockSetSelectedFile, }); render( , ); expect(screen.getByText("No files changed")).toBeInTheDocument(); }); it("closes on Escape", () => { render( , ); fireEvent.keyDown(document, { key: "Escape" }); expect(mockOnClose).toHaveBeenCalledTimes(1); }); });