import { describe, expect, it } from "vite-plus/test";
import { renderToStaticMarkup } from "react-dom/server";
import { resolveThreadLineageWindow, ThreadLineageRowList } from "./ThreadRelationshipsControl";
const rows = Array.from({ length: 20 }, (_, index) => `row-${index}`);
function renderRowList(visibleCount: number) {
const { visibleRows, hiddenCount } = resolveThreadLineageWindow(rows, visibleCount);
return renderToStaticMarkup(
{}}>
{visibleRows.map((row) => (
{row}
))}
,
);
}
describe("thread lineage row list", () => {
it("shows six rows before the first expansion", () => {
const { visibleRows, hiddenCount } = resolveThreadLineageWindow(rows, 6);
expect(visibleRows).toEqual(rows.slice(0, 6));
expect(hiddenCount).toBe(14);
});
it("offers one page at a time", () => {
expect(renderRowList(6)).toContain("Show 12 more");
expect(renderRowList(6 + 12)).toContain("Show 2 more");
});
it("omits the expansion affordance when everything fits", () => {
const markup = renderRowList(rows.length);
expect(markup).not.toContain("more");
expect(resolveThreadLineageWindow(rows.slice(0, 6), 6).hiddenCount).toBe(0);
});
it("keeps the rows in a bounded, labelled scroll region and the button outside it", () => {
const markup = renderRowList(6);
const list = /
]*)>/.exec(markup)?.[1] ?? "";
expect(list).toContain('aria-label="Related threads"');
expect(list).toContain("max-h-[13.5rem]");
expect(list).toContain("overflow-y-auto");
expect(list).toContain("overscroll-contain");
expect(markup.indexOf("
")).toBeLessThan(markup.indexOf("