// @vitest-environment jsdom import { cleanup, fireEvent, render, screen, within } from "@testing-library/react"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { FileList } from "@/components/files/file-list"; import type { UserFile } from "@/lib/api"; import { useFilesPageStore } from "@/stores/files-page-store"; const files: UserFile[] = [ { id: "image-file", originalName: "photo.png", mimeType: "image/png", size: 1024, width: 100, height: 100, version: 1, toolChain: [], createdAt: "2026-07-24T00:00:00.000Z", }, { id: "video-file", originalName: "clip.mp4", mimeType: "video/mp4", size: 2048, width: 1920, height: 1080, version: 1, toolChain: [], createdAt: "2026-07-24T00:00:00.000Z", }, ]; const initialState = useFilesPageStore.getInitialState(); beforeEach(() => { Element.prototype.scrollIntoView = vi.fn(); useFilesPageStore.setState( { ...initialState, files, total: files.length, checkedIds: new Set(), fetchFiles: vi.fn(async () => {}), }, true, ); }); afterEach(() => { cleanup(); useFilesPageStore.setState({ ...initialState, checkedIds: new Set() }, true); vi.restoreAllMocks(); }); describe("FileList accessibility", () => { it("uses native list items with separate file buttons and checkboxes", () => { render(); const list = screen.getByRole("list"); expect(within(list).getAllByRole("listitem")).toHaveLength(2); expect(screen.queryByRole("listbox")).toBeNull(); const fileButton = screen.getByRole("button", { name: "photo.png" }); const checkbox = screen.getByRole("checkbox", { name: "Select File: photo.png" }); expect(fileButton.contains(checkbox)).toBe(false); const descriptionId = fileButton.getAttribute("aria-describedby"); expect(descriptionId).not.toBeNull(); expect(document.getElementById(descriptionId ?? "")?.textContent).toContain("Version 1"); expect(document.getElementById(descriptionId ?? "")?.textContent).toContain("1.0 KB"); }); it("moves roving focus between file buttons with the arrow keys", () => { render(); const imageButton = screen.getByRole("button", { name: "photo.png" }); const videoButton = screen.getByRole("button", { name: "clip.mp4" }); expect(imageButton.tabIndex).toBe(0); expect(videoButton.tabIndex).toBe(-1); imageButton.focus(); fireEvent.keyDown(imageButton, { key: "ArrowDown" }); expect(useFilesPageStore.getState().selectedFileId).toBe("video-file"); expect(document.activeElement).toBe(videoButton); expect(imageButton.tabIndex).toBe(-1); expect(videoButton.tabIndex).toBe(0); }); it("does not activate a disabled file through the keyboard", () => { const onFileActivate = vi.fn(); useFilesPageStore.setState({ selectedFileId: "video-file" }); render(); const videoButton = screen.getByRole("button", { name: "clip.mp4" }); expect((videoButton as HTMLButtonElement).disabled).toBe(true); fireEvent.keyDown(videoButton, { key: "Enter" }); fireEvent.click(videoButton); expect(onFileActivate).not.toHaveBeenCalled(); }); it("keeps filtered files available to independent bulk management", () => { render(); const videoCheckbox = screen.getByRole("checkbox", { name: "Select File: clip.mp4" }); const selectAll = screen.getByRole("checkbox", { name: "Select File: My Files" }); expect((videoCheckbox as HTMLInputElement).disabled).toBe(false); fireEvent.click(selectAll); expect(useFilesPageStore.getState().checkedIds).toEqual(new Set(["image-file", "video-file"])); }); });