import { describe, expect, it } from "vitest"; import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row"; import { currentWeekMonday } from "@/domain/work-orders/utils/list-week-utils"; import { buildSelectedDayGroup, firstWeekday, formatDayTabLabel, initialSelectedDay, isDayScopedSearchEmpty, isUnassignedQueueReady, rowMatchesSelectedDay, scheduledDayTab, weekdaysMonFri, } from "@/domain/work-orders/utils/week-day-nav-utils"; import { addDaysIso } from "@/domain/work-orders/utils/wizard-date-utils"; function row(overrides: Partial): WorkOrderTableRow { return { id: "1", woNumber: "1", site: "", type: "PM", severity: null, dispatcherId: "d1", dispatcherName: "D", scheduledOn: "", completedDate: "", targetWeek: "", dayGroup: "", dayLabel: "", location: "", locationId: "", pm: "", serviceNotes: "", extraServices: [], vendorId: "", company: "", tech: "", techPhone: "", apptStart: "", apptEnd: "", apptTime: "", status: "Incomplete", docStatus: "No", pocName: "", pocPhone: "", pocNotes: "", additionalContacts: [], dueDate: "", rescheduleCount: 0, carriedOver: 0, isAddOn: false, originalWeek: "", originalDate: "", isPastDue: false, scheduleWeekOnly: false, mediaCount: 0, title: "", priority: "", primaryDispatchId: null, rowVersion: "", dispatchRowVersion: "", flagColor: null, ...overrides, }; } describe("week-day-nav-utils (SH-240)", () => { it("lists Mon–Fri of the active week", () => { expect(weekdaysMonFri("2026-05-18")).toEqual([ "2026-05-18", "2026-05-19", "2026-05-20", "2026-05-21", "2026-05-22", ]); }); it("formats day tabs as Title · MM/DD", () => { expect(formatDayTabLabel("2026-05-18")).toBe("Mon · 05/18"); expect(formatDayTabLabel("2026-05-22")).toBe("Fri · 05/22"); }); it("resets to Monday when the week changes", () => { expect(firstWeekday("2026-05-25")).toBe("2026-05-25"); }); it("selects today on the live week when today is a weekday", () => { const liveMonday = currentWeekMonday(); const wednesday = addDaysIso(liveMonday, 2); expect(initialSelectedDay(liveMonday, wednesday)).toBe(wednesday); }); it("selects Monday on a non-live week", () => { expect(initialSelectedDay("2026-05-18", "2026-05-20")).toBe("2026-05-18"); }); it("excludes unscheduled and other days from the selected day group", () => { const monday = row({ id: "mon", scheduledOn: "2026-05-18", dayGroup: "05/18", dayLabel: "MON · 05/18", }); const wednesday = row({ id: "wed", scheduledOn: "2026-05-20", dayGroup: "05/20", dayLabel: "WED · 05/20", }); const unscheduled = row({ id: "us", scheduledOn: "", scheduleWeekOnly: true }); expect(rowMatchesSelectedDay(unscheduled, "2026-05-18")).toBe(false); expect(rowMatchesSelectedDay(monday, "2026-05-18")).toBe(true); const group = buildSelectedDayGroup("2026-05-18", "2026-05-18", [ monday, wednesday, unscheduled, ]); expect(group.date).toBe("2026-05-18"); expect(group.label).toBe("Mon · 05/18"); expect(group.items.map((item) => item.id)).toEqual(["mon"]); }); it("maps a scheduled weekday onto its week and day tab", () => { expect(scheduledDayTab("2026-05-20")).toEqual({ weekMonday: "2026-05-18", selectedDayIso: "2026-05-20", }); }); it("treats search as empty only when the selected day and Unassigned have no hits", () => { expect( isDayScopedSearchEmpty({ searchActive: true, unassignedCount: 0, dayItemCount: 0, unassignedQueueReady: true, }), ).toBe(true); expect( isDayScopedSearchEmpty({ searchActive: true, unassignedCount: 0, dayItemCount: 1, unassignedQueueReady: true, }), ).toBe(false); expect( isDayScopedSearchEmpty({ searchActive: true, unassignedCount: 2, dayItemCount: 0, unassignedQueueReady: true, }), ).toBe(false); expect( isDayScopedSearchEmpty({ searchActive: false, unassignedCount: 0, dayItemCount: 0, unassignedQueueReady: true, }), ).toBe(false); }); it("does not treat search as empty while the Unassigned queue is loading or failed", () => { expect(isUnassignedQueueReady(true, null)).toBe(false); expect(isUnassignedQueueReady(false, new Error("queue unavailable"))).toBe(false); expect(isUnassignedQueueReady(false, null)).toBe(true); expect( isDayScopedSearchEmpty({ searchActive: true, unassignedCount: 0, dayItemCount: 0, unassignedQueueReady: false, }), ).toBe(false); }); }); describe("week-day-nav-utils carry-over display", () => { it("places a prior-week unresolved WO on the same weekday of the viewed week", () => { const carried = row({ id: "co", scheduledOn: "2026-05-13", dayGroup: "05/13", status: "Scheduled", carriedOver: 2, originalWeek: "2026-05-11", }); const nativeWed = row({ id: "native", scheduledOn: "2026-05-20", dayGroup: "05/20", status: "Scheduled", }); expect(rowMatchesSelectedDay(carried, "2026-05-20", "2026-05-18")).toBe(true); expect(rowMatchesSelectedDay(carried, "2026-05-18", "2026-05-18")).toBe(false); const group = buildSelectedDayGroup("2026-05-18", "2026-05-20", [carried, nativeWed]); expect(group.items.map((item) => item.id)).toEqual(["co", "native"]); }); it("does not map completed carry-overs onto the viewed week", () => { const completed = row({ id: "done", scheduledOn: "2026-05-13", status: "Completed", carriedOver: 2, }); expect(rowMatchesSelectedDay(completed, "2026-05-20", "2026-05-18")).toBe(false); expect(buildSelectedDayGroup("2026-05-18", "2026-05-20", [completed]).items).toEqual([]); }); it("keeps unscheduled rows out of day groups", () => { const unscheduled = row({ id: "us", scheduledOn: "", scheduleWeekOnly: true, carriedOver: 2 }); expect(rowMatchesSelectedDay(unscheduled, "2026-05-18", "2026-05-18")).toBe(false); }); });