// @vitest-environment jsdom
import { cleanup, fireEvent, render } from "@testing-library/react";
import type * as React from "react";
import { afterEach, describe, expect, expectTypeOf, it, vi } from "vitest";
import { Card } from "./composites/card";
import { PaginationLink } from "./composites/pagination";
import { ControlSection } from "./control-layout";
import { PanelContentSurface, PanelSurface } from "./panel/panel-surface";
afterEach(cleanup);
const composedHostFamilies = [
["composite", Card],
["control layout", ControlSection],
["panel", PanelSurface],
["panel content", PanelContentSurface],
] as const;
describe("composed host prop boundary", () => {
for (const [family, Component] of composedHostFamilies) {
it(`sanitizes external ${family} host props and preserves ordinary props`, () => {
const onClick = vi.fn();
const externalProps = {
"aria-label": `${family} surface`,
"data-testid": "surface",
dangerouslySetInnerHTML: { __html: "" },
id: `${family.replaceAll(" ", "-")}-surface`,
onClick,
role: "button",
tabIndex: 0,
} as const;
const { getByTestId } = render();
const surface = getByTestId("surface");
fireEvent.click(surface);
expect(surface.id).toBe(externalProps.id);
expect(surface.getAttribute("aria-label")).toBe(externalProps["aria-label"]);
expect(surface.getAttribute("role")).toBeNull();
expect(surface.getAttribute("tabindex")).toBeNull();
expect(surface.querySelector("button")).toBeNull();
expect(onClick).not.toHaveBeenCalled();
});
}
it("sanitizes the non-overflow panel content branch", () => {
const onClick = vi.fn();
const UnsafePanelContentSurface = PanelContentSurface as React.ComponentType<
React.HTMLAttributes & { scrollFadeMode?: "always" | "overflow" }
>;
const { getByTestId } = render(
,
);
const surface = getByTestId("overflow-surface");
fireEvent.click(surface);
expect(surface.getAttribute("role")).toBeNull();
expect(surface.getAttribute("tabindex")).toBeNull();
expect(onClick).not.toHaveBeenCalled();
});
it("preserves pagination anchor content and navigation props", () => {
const { getByRole } = render(
Next,
);
const link = getByRole("link", { name: "Next" });
expect(link.getAttribute("href")).toBe("/next-page");
});
it("preserves pagination anchor click behavior through the public Button", () => {
const onClick = vi.fn();
const onClickCapture = vi.fn();
const onKeyDown = vi.fn();
const { getByRole } = render(
Next
,
);
const link = getByRole("link", { name: "Next" });
fireEvent.click(link);
fireEvent.keyDown(link, { key: "Enter" });
expect(onClick).toHaveBeenCalledTimes(1);
expect(onClickCapture).toHaveBeenCalledTimes(1);
expect(onKeyDown).toHaveBeenCalledTimes(1);
expect(link.tabIndex).toBe(2);
expect(link.getAttribute("href")).toBe("/next-page");
});
it("exposes complete anchor interaction props with required href", () => {
expectTypeOf>().toMatchTypeOf<{
href: string;
onClickCapture?: React.MouseEventHandler;
onKeyDown?: React.KeyboardEventHandler;
tabIndex?: number;
}>();
});
});