// @vitest-environment jsdom // // The rendering integration of SortControl (its pickSort/heal decision logic is covered in // columnSort.test.ts). Labels are plain props here — no i18n needed. import { describe, it, expect, vi, afterEach } from "vitest"; import { render, screen, fireEvent, cleanup } from "@testing-library/react"; import SortControl from "./SortControl"; import type { SortOption, SortState } from "../lib/columnSort"; const OPTS: SortOption[] = [ { key: "date", label: "Date", defaultDir: "desc" }, { key: "title", label: "Title" }, { key: "shuffle", label: "Shuffle", directionless: true }, ]; function renderControl(sort: SortState, extra: Record = {}) { const onChange = vi.fn(); render( , ); return { onChange }; } afterEach(cleanup); describe("SortControl", () => { it("renders one option per SortOption, no empty option without defaultLabel", () => { renderControl({ key: "title", dir: "asc" }); expect(screen.getAllByRole("option").map((o) => o.textContent)).toEqual([ "Date", "Title", "Shuffle", ]); }); it("adds a leading no-sort option when defaultLabel is set (tables)", () => { renderControl(null, { defaultLabel: "None" }); const none = screen.getByRole("option", { name: "None" }) as HTMLOptionElement; expect(none.value).toBe(""); }); it("falls back to the first option (not a blank select) for an unavailable key without defaultLabel", () => { renderControl({ key: "ghost", dir: "asc" }); expect((screen.getByRole("combobox") as HTMLSelectElement).value).toBe("date"); }); it("picking a new option fires onChange at that option's defaultDir", () => { const { onChange } = renderControl({ key: "title", dir: "asc" }); fireEvent.change(screen.getByRole("combobox"), { target: { value: "date" } }); expect(onChange).toHaveBeenCalledWith({ key: "date", dir: "desc" }); }); it("shows the direction toggle for a directional sort and flips it on click", () => { const { onChange } = renderControl({ key: "date", dir: "desc" }); const toggle = screen.getByRole("button", { name: "Descending" }); fireEvent.click(toggle); expect(onChange).toHaveBeenCalledWith({ key: "date", dir: "asc" }); }); it("hides the direction toggle for a directionless sort", () => { renderControl({ key: "shuffle", dir: "desc" }); expect(screen.queryByRole("button")).toBeNull(); }); it("renders the trailing adornment", () => { renderControl( { key: "shuffle", dir: "desc" }, { trailing: , }, ); expect(screen.getByRole("button", { name: "Reshuffle" })).toBeTruthy(); }); });