import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { ResultsPagination } from "./results-pagination"; const CHOOSE_PAGE = "Choose results page"; let mobile = true; vi.mock("@/hooks/use-responsive-breakpoint", () => ({ useResponsiveBreakpoint: () => ({ isMobile: mobile }), })); beforeEach(() => { mobile = true; }); afterEach(cleanup); // @covers AC-INTEGRATIONS-GITHUB-MOBILE-001.4 describe("phone pagination", () => { it("keeps focus in the page drawer when the current page disappears after a refresh", async () => { const onPageChange = vi.fn(); const { rerender } = render( , ); rerender(); fireEvent.click(screen.getByRole("button", { name: CHOOSE_PAGE })); const dialog = screen.getByRole("dialog", { name: CHOOSE_PAGE }); await waitFor(() => expect(dialog.contains(document.activeElement)).toBe(true)); expect(onPageChange).not.toHaveBeenCalled(); fireEvent.click(screen.getByRole("button", { name: "Page 2 of 2" })); expect(onPageChange).toHaveBeenCalledExactlyOnceWith(2); }); it("offers direct selection up to GitHub's 1000-result cap", () => { const onPageChange = vi.fn(); render(); const selector = screen.getByLabelText(CHOOSE_PAGE, { selector: "button,select" }); expect(selector.tagName).toBe("BUTTON"); expect(screen.getByText("1–25 of 1000+")).not.toBeNull(); expect(screen.getByRole("button", { name: "Previous page" }).hasAttribute("disabled")).toBe( true, ); fireEvent.click(selector); expect(screen.getByRole("dialog", { name: CHOOSE_PAGE })).toBeTruthy(); expect(screen.getAllByRole("button", { name: /^Page \d+ of 40$/ })).toHaveLength(40); fireEvent.click(screen.getByRole("button", { name: "Page 5 of 40" })); expect(onPageChange).toHaveBeenCalledExactlyOnceWith(5); expect(selector.getAttribute("aria-expanded")).toBe("false"); }); it("bounds next and previous at the last available page", () => { const onPageChange = vi.fn(); render(); expect(screen.getByLabelText(CHOOSE_PAGE, { selector: "button,select" }).textContent).toBe( "Page 40 of 40", ); expect(screen.getByRole("button", { name: "Next page" }).hasAttribute("disabled")).toBe(true); fireEvent.click(screen.getByRole("button", { name: "Previous page" })); expect(onPageChange).toHaveBeenCalledExactlyOnceWith(39); }); it("marks the current page and dismisses without fetching it again", () => { const onPageChange = vi.fn(); render(); const selector = screen.getByLabelText(CHOOSE_PAGE, { selector: "button,select" }); fireEvent.click(selector); const current = screen.getByRole("button", { name: "Page 5 of 40" }); expect(current.getAttribute("aria-current")).toBe("page"); fireEvent.click(current); expect(selector.getAttribute("aria-expanded")).toBe("false"); expect(onPageChange).not.toHaveBeenCalled(); }); it("retains numbered pagination on desktop", () => { mobile = false; render(); expect(screen.queryByRole("combobox")).toBeNull(); expect(screen.getByRole("link", { name: "40" })).not.toBeNull(); }); });