import { describe, expect, it } from "vitest"; import { DAY_PAGE_SIZE_OPTIONS, DEFAULT_DAY_PAGE_SIZE, asDayPageSize, findItemPageIndex, formatDayPaginationSummary, nextSearchPageIfOutOfRange, pageIndexForItem, paginateItems, pickBoardPager, shouldShowDayPagination, shouldShowSearchPagination, } from "@/domain/work-orders/utils/day-pagination"; describe("day pagination utils (SH-241)", () => { it("defaults to 50 and exposes 25/50/100/200", () => { expect(DEFAULT_DAY_PAGE_SIZE).toBe(50); expect(DAY_PAGE_SIZE_OPTIONS).toEqual([25, 50, 100, 200]); expect(asDayPageSize(200)).toBe(200); expect(asDayPageSize(13)).toBe(DEFAULT_DAY_PAGE_SIZE); }); it("paginates 60 items at 50 per page", () => { const items = Array.from({ length: 60 }, (_, index) => index); const first = paginateItems(items, 0, 50); expect(first.visible).toHaveLength(50); expect(first.pageCount).toBe(2); const second = paginateItems(items, 1, 50); expect(second.visible).toEqual(items.slice(50)); }); it("re-paginates immediately when page size changes", () => { const items = Array.from({ length: 60 }, (_, index) => index); expect(paginateItems(items, 0, 25).visible).toHaveLength(25); expect(paginateItems(items, 0, 25).pageCount).toBe(3); }); it("clamps an out-of-range page to the last page", () => { const paged = paginateItems([1, 2, 3], 9, 2); expect(paged.pageIndex).toBe(1); expect(paged.visible).toEqual([3]); }); it("shows pagination in day view even when the page is not full", () => { expect( shouldShowDayPagination({ flatListMode: false, isLoading: false, noSearchResults: false, }), ).toBe(true); }); it("hides pagination in flat-list / loading / empty search", () => { expect( shouldShowDayPagination({ flatListMode: true, isLoading: false, noSearchResults: false, }), ).toBe(false); expect( shouldShowDayPagination({ flatListMode: false, isLoading: true, noSearchResults: false, }), ).toBe(false); expect( shouldShowDayPagination({ flatListMode: false, isLoading: false, noSearchResults: true, }), ).toBe(false); }); it("shows search pagination when advanced filters return rows", () => { expect(shouldShowSearchPagination({ isLoading: false, hasResults: true })).toBe(true); expect(shouldShowSearchPagination({ isLoading: true, hasResults: true })).toBe(false); expect(shouldShowSearchPagination({ isLoading: false, hasResults: false })).toBe(false); }); it("shows search pagination when the current page is empty but totalCount is positive", () => { const pager = pickBoardPager({ advActive: true, isLoading: false, noSearchResults: false, advResultCount: 0, search: { page: 99, pageSize: 50, totalCount: 1778 }, day: { pageSize: 50, pageIndex: 0, pageCount: 1, itemCount: 0, footerLabel: "Mon · 08/17", }, }); expect(pager.show).toBe(true); expect(pager.itemCount).toBe(1778); expect(pager.pageCount).toBe(36); expect(pager.pageIndex).toBe(35); expect(pager.footerLabel).toBe("Results"); }); it("pages a 1778-row search at 50 per page without dumping the universe", () => { const pager = pickBoardPager({ advActive: true, isLoading: false, noSearchResults: false, advResultCount: 50, search: { page: 0, pageSize: 50, totalCount: 1778 }, day: { pageSize: 50, pageIndex: 0, pageCount: 1, itemCount: 0, footerLabel: "Mon · 08/17", }, }); expect(pager.show).toBe(true); expect(pager.itemCount).toBe(1778); expect(pager.pageCount).toBe(36); expect(pager.pageIndex).toBe(0); expect(pager.footerLabel).toBe("Results"); }); it("maps a row past the first page onto page 2 at the default size", () => { const items = Array.from({ length: 60 }, (_, index) => ({ id: `wo-${index}` })); expect(pageIndexForItem(50, 50)).toBe(1); expect(findItemPageIndex(items, "wo-55", 50)).toBe(1); expect(findItemPageIndex(items, "missing", 50)).toBeNull(); }); it("formats the AAP footer summary", () => { expect(formatDayPaginationSummary("Mon · 06/01", 9)).toBe("MON · 06/01 · 9 items"); expect(formatDayPaginationSummary("Tue · 06/02", 1)).toBe("TUE · 06/02 · 1 item"); }); }); describe("nextSearchPageIfOutOfRange", () => { it("returns the last valid page when a search shrinks to one page", () => { expect(nextSearchPageIfOutOfRange({ page: 1, pageSize: 50, totalCount: 40 })).toBe(0); }); it("leaves a still-valid second page alone", () => { expect(nextSearchPageIfOutOfRange({ page: 1, pageSize: 50, totalCount: 60 })).toBeNull(); }); it("does not pull an empty result set onto page 1", () => { expect(nextSearchPageIfOutOfRange({ page: 1, pageSize: 50, totalCount: 0 })).toBeNull(); }); it("leaves the last valid page alone", () => { expect(nextSearchPageIfOutOfRange({ page: 0, pageSize: 50, totalCount: 40 })).toBeNull(); }); });