import { afterEach, describe, expect, it, vi } from "vitest";
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
vi.mock("react-i18next", () => ({
useTranslation: () => ({ t: (key: string) => key }),
}));
import {
Facts,
PanelSearch,
PanelShell,
Segmented,
ViewToggle,
gridSizeStyle,
} from "@/components/panel-layout";
afterEach(cleanup);
describe("PanelSearch", () => {
it("clears with the button and with Esc", () => {
const onChange = vi.fn();
const { rerender } = render(
,
);
fireEvent.click(screen.getByLabelText("panel.clearSearch"));
expect(onChange).toHaveBeenLastCalledWith("");
rerender();
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
expect(onChange).toHaveBeenCalledTimes(2);
});
it("hides the clear button while empty", () => {
render( {}} />);
expect(screen.queryByLabelText("panel.clearSearch")).toBeNull();
});
});
describe("Segmented", () => {
it("marks the active option and reports a pick", () => {
const onChange = vi.fn();
render(
,
);
const radios = screen.getAllByRole("radio");
expect(radios[0].getAttribute("aria-checked")).toBe("true");
fireEvent.click(radios[1]);
expect(onChange).toHaveBeenCalledWith("credentials");
});
});
describe("ViewToggle", () => {
it("switches view and density", () => {
const onView = vi.fn();
const onDensity = vi.fn();
render(
,
);
fireEvent.click(screen.getByLabelText("panel.listView"));
expect(onView).toHaveBeenCalledWith("list");
fireEvent.click(screen.getByLabelText("panel.compactRows"));
expect(onDensity).toHaveBeenCalledWith("compact");
});
it("shows the columns picker only in grid view", () => {
const props = { onView: vi.fn(), columns: "auto" as const };
const { rerender } = render(
,
);
expect(screen.getByLabelText("panel.columns.title")).toBeTruthy();
rerender();
expect(screen.queryByLabelText("panel.columns.title")).toBeNull();
rerender();
expect(screen.queryByLabelText("panel.columns.title")).toBeNull();
});
});
describe("gridSizeStyle", () => {
it("fits auto cards to the pane", () => {
expect(gridSizeStyle("auto", 280).gridTemplateColumns).toBe(
"repeat(auto-fill, minmax(min(100%, 280px), 1fr))",
);
});
it("splits the width for a fixed count", () => {
expect(gridSizeStyle("4").gridTemplateColumns).toContain(
"(100% - 3 * 0.5rem) / 4",
);
});
});
describe("Facts", () => {
it("puts a rule only between facts", () => {
const { container } = render(
one
{null}
two
,
);
expect(container.querySelectorAll("[aria-hidden]")).toHaveLength(1);
});
it("separates facts passed inside a fragment", () => {
const { container } = render(
<>
Termix
{false}
v1.0.0
Monitoring
>
,
);
expect(container.querySelectorAll("[aria-hidden]")).toHaveLength(2);
});
});
describe("PanelShell", () => {
it("draws the header, toolbar and footer", () => {
render(
toolbar}
footer={footer}
>
body
,
);
expect(screen.getByText("Docker")).toBeTruthy();
expect(screen.getByText("2 running")).toBeTruthy();
expect(screen.getByText("toolbar")).toBeTruthy();
expect(screen.getByText("footer")).toBeTruthy();
});
});