74 lines
3.1 KiB
TypeScript
74 lines
3.1 KiB
TypeScript
import { fireEvent, render, screen, within } from "@testing-library/react";
|
|
import { expect, test, vi } from "vitest";
|
|
|
|
import type { PageData } from "@/shared/api/pagination";
|
|
import { ResourcePagination } from "@/shared/ui/resource-pagination";
|
|
|
|
const pageData: PageData<string> = {
|
|
totalCount: 42,
|
|
page: 1,
|
|
size: 20,
|
|
hasNext: true,
|
|
items: [],
|
|
};
|
|
|
|
test("ResourcePagination uses PageData and real buttons for accessible page movement", () => {
|
|
const onPageChange = vi.fn();
|
|
const onSizeChange = vi.fn();
|
|
|
|
render(<ResourcePagination data={pageData} onPageChange={onPageChange} onSizeChange={onSizeChange} />);
|
|
|
|
const previous = screen.getByRole("button", { name: "이전 페이지" });
|
|
const next = screen.getByRole("button", { name: "다음 페이지" });
|
|
|
|
expect(previous.tagName).toBe("BUTTON");
|
|
expect(next).toBeEnabled();
|
|
expect(screen.getByText("총 42개 · 2페이지")).toBeInTheDocument();
|
|
|
|
fireEvent.click(previous);
|
|
fireEvent.click(next);
|
|
fireEvent.change(screen.getByLabelText("페이지 크기"), { target: { value: "50" } });
|
|
|
|
expect(onPageChange).toHaveBeenNthCalledWith(1, 0);
|
|
expect(onPageChange).toHaveBeenNthCalledWith(2, 2);
|
|
expect(onSizeChange).toHaveBeenCalledWith(50);
|
|
});
|
|
|
|
test("ResourcePagination disables unavailable previous and next actions", () => {
|
|
render(<ResourcePagination data={{ ...pageData, page: 0, hasNext: false }} onPageChange={vi.fn()} onSizeChange={vi.fn()} />);
|
|
|
|
expect(screen.getByRole("button", { name: "이전 페이지" })).toBeDisabled();
|
|
expect(screen.getByRole("button", { name: "다음 페이지" })).toBeDisabled();
|
|
});
|
|
|
|
test("ResourcePagination connects each page size label to a unique select", () => {
|
|
const { container } = render(
|
|
<>
|
|
<ResourcePagination data={pageData} onPageChange={vi.fn()} onSizeChange={vi.fn()} />
|
|
<ResourcePagination data={{ ...pageData, page: 0 }} onPageChange={vi.fn()} onSizeChange={vi.fn()} />
|
|
</>,
|
|
);
|
|
|
|
const selects = screen.getAllByLabelText("페이지 크기");
|
|
const selectIds = selects.map((select) => select.id);
|
|
const labels = Array.from(container.querySelectorAll("label"));
|
|
|
|
expect(new Set(selectIds).size).toBe(selectIds.length);
|
|
expect(labels.map((label) => label.control)).toEqual(selects);
|
|
});
|
|
|
|
test("ResourcePagination separates page size from stacked mobile movement controls", () => {
|
|
render(<ResourcePagination data={pageData} onPageChange={vi.fn()} onSizeChange={vi.fn()} />);
|
|
|
|
const sizeControls = screen.getByRole("group", { name: "페이지 크기 설정" });
|
|
const movementControls = screen.getByRole("group", { name: "페이지 이동" });
|
|
const previous = within(movementControls).getByRole("button", { name: "이전 페이지" });
|
|
const next = within(movementControls).getByRole("button", { name: "다음 페이지" });
|
|
|
|
expect(within(sizeControls).getByLabelText("페이지 크기")).toBeInTheDocument();
|
|
expect(sizeControls).not.toContainElement(previous);
|
|
expect(movementControls).toHaveClass("grid-cols-1");
|
|
expect(previous).toHaveClass("min-h-11", "w-full", "whitespace-nowrap");
|
|
expect(next).toHaveClass("min-h-11", "w-full", "whitespace-nowrap");
|
|
});
|