shoc-frontend-new/src/test/app/(protected)/workorders/wo-table-adv-search-pagination.test.tsx

200 lines
5.7 KiB
TypeScript

import { fireEvent, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { WoTable } from "@/app/(protected)/workorders/_components/list/table/wo-table";
import type { ReturnTypeOfUseWorkOrdersTableData } from "@/app/(protected)/workorders/_components/list/table/wo-table-types";
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
import { renderWithProviders } from "@/test/test-utils";
vi.mock("@/domain/locations/use-cases/use-location-sites", () => ({
useLocationSites: () => ({ data: [] }),
}));
vi.mock("@/app/(protected)/workorders/_components/list/table/use-wo-table-inline-create", () => ({
useWoTableInlineCreate: () => ({ handleInlineSave: vi.fn(), saving: false }),
}));
function makeRow(overrides: Partial<WorkOrderTableRow> = {}): WorkOrderTableRow {
return {
id: "1",
woNumber: "24991",
site: "CLV2",
type: "PM",
severity: null,
dispatcherId: "",
dispatcherName: "",
scheduledOn: "",
completedDate: "",
targetWeek: "",
dayGroup: "",
dayLabel: "",
location: "Cleveland, OH",
locationId: "",
pm: "Backflow",
serviceNotes: "",
extraServices: [],
company: "",
tech: "",
techPhone: "",
apptStart: "",
apptEnd: "",
apptTime: "—",
status: "Incomplete",
docStatus: "No",
pocName: "",
pocPhone: "",
pocNotes: "",
dueDate: "",
rescheduleCount: 0,
carriedOver: 0,
isAddOn: false,
originalWeek: "",
originalDate: "",
isPastDue: false,
scheduleWeekOnly: false,
mediaCount: 0,
title: "",
priority: "",
vendorId: "",
primaryDispatchId: null,
rowVersion: "",
dispatchRowVersion: "",
flagColor: null,
additionalContacts: [],
...overrides,
};
}
function tableData(
overrides: Partial<ReturnTypeOfUseWorkOrdersTableData> = {},
): ReturnTypeOfUseWorkOrdersTableData {
const pageRows = [
makeRow({ id: "wo-0", woNumber: "WO-0" }),
makeRow({ id: "wo-49", woNumber: "WO-49" }),
];
return {
rows: pageRows,
isLoading: false,
isFetching: false,
error: null,
refetch: vi.fn(),
advActive: true,
advResults: pageRows,
unassigned: [],
unassignedError: null,
unassignedLoading: false,
unscheduled: [],
displayGroups: [],
searchActive: false,
noSearchResults: false,
isEmptyWeek: false,
todayKey: null,
draftDayKey: null,
draft: { locationId: "", site: "" },
setDraft: vi.fn(),
unassignedOpen: true,
setUnassignedOpen: vi.fn(),
unschedOpen: true,
setUnschedOpen: vi.fn(),
selectedId: null,
setSelectedId: vi.fn(),
selectedRow: null,
flashId: null,
triggerFlash: vi.fn(),
revealScheduledRow: vi.fn(),
dragViz: { dragId: null, overId: null },
setDragViz: vi.fn(),
dragState: { current: { dragId: null, overId: null } },
patchRow: vi.fn(),
clearRowPatch: vi.fn(),
reorderRows: vi.fn(),
endDrag: vi.fn(),
startDayDraft: vi.fn(),
cancelDraft: vi.fn(),
addRow: vi.fn(),
scopeTotalCount: 1778,
totalCount: 2,
search: "",
showDayPagination: true,
dayPageSize: 50,
dayPageIndex: 0,
dayPageCount: 36,
dayItemCount: 1778,
dayFooterLabel: "Results",
setDayPageSize: vi.fn(),
goToPrevDayPage: vi.fn(),
goToNextDayPage: vi.fn(),
...overrides,
} as ReturnTypeOfUseWorkOrdersTableData;
}
describe("WoTable advanced-search pagination", () => {
it("pages the flat Unassigned search without a pin or a 1778-row dump", () => {
const goToNextDayPage = vi.fn();
const data = tableData({ goToNextDayPage });
renderWithProviders(
<WoTable
tableData={data}
users={[]}
sites={[]}
vendors={[]}
pmTypes={[]}
weekMonday="2026-05-18"
onNavigateToDay={vi.fn()}
onOpenSlideOver={vi.fn()}
onOpenMedia={vi.fn()}
onPatch={vi.fn()}
/>,
{ withAuth: false },
);
expect(screen.queryByRole("button", { name: /Unassigned/ })).not.toBeInTheDocument();
expect(screen.getByText("WO-0")).toBeInTheDocument();
expect(screen.getByText("WO-49")).toBeInTheDocument();
expect(screen.queryByText("WO-50")).not.toBeInTheDocument();
expect(screen.getByText("RESULTS · 1778 items")).toBeInTheDocument();
expect(screen.getByText("Page 1 of 36")).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "Next page" }));
expect(goToNextDayPage).toHaveBeenCalled();
expect(screen.getByRole("button", { name: "Next page" })).toBeEnabled();
expect(screen.getByRole("button", { name: "Previous page" })).toBeDisabled();
});
it("keeps the search pager when the current page is empty but matches remain", () => {
const goToPrevDayPage = vi.fn();
const data = tableData({
rows: [],
advResults: [],
totalCount: 0,
scopeTotalCount: 1778,
dayPageIndex: 35,
dayPageCount: 36,
goToPrevDayPage,
});
renderWithProviders(
<WoTable
tableData={data}
users={[]}
sites={[]}
vendors={[]}
pmTypes={[]}
weekMonday="2026-05-18"
onNavigateToDay={vi.fn()}
onOpenSlideOver={vi.fn()}
onOpenMedia={vi.fn()}
onPatch={vi.fn()}
/>,
{ withAuth: false },
);
expect(screen.queryByText("No work orders match these filters")).not.toBeInTheDocument();
expect(screen.getByText("RESULTS · 1778 items")).toBeInTheDocument();
expect(screen.getByText("Page 36 of 36")).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Previous page" })).toBeEnabled();
fireEvent.click(screen.getByRole("button", { name: "Previous page" }));
expect(goToPrevDayPage).toHaveBeenCalled();
});
});