mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 17:42:06 +00:00
222 lines
6.3 KiB
TypeScript
222 lines
6.3 KiB
TypeScript
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>): 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);
|
||
});
|
||
});
|