import { describe, expect, it } from "vitest"; import { buildSlideOverPatch, isSlideOverDraftDirty, } from "@/domain/work-orders/utils/slide-over-draft"; import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row"; /** * Mirrors the failed-save path: optimistic parent row absorbs the patch, then * rolls back, while draft is compared against a frozen pre-save baseline. */ function afterFailedOptimisticSave(input: { baseline: WorkOrderTableRow; draft: WorkOrderTableRow; optimisticParent: WorkOrderTableRow; rolledBackParent: WorkOrderTableRow; }) { const dirtyAgainstOptimistic = isSlideOverDraftDirty(input.draft, input.optimisticParent); const dirtyAgainstBaseline = isSlideOverDraftDirty(input.draft, input.baseline); const dirtyAgainstRolledBack = isSlideOverDraftDirty(input.draft, input.rolledBackParent); const retryPatch = buildSlideOverPatch(input.draft, input.baseline); return { dirtyAgainstOptimistic, dirtyAgainstBaseline, dirtyAgainstRolledBack, retryPatch, canRetry: dirtyAgainstBaseline && Object.keys(retryPatch).length > 0, }; } function row(overrides: Partial = {}): WorkOrderTableRow { return { id: 1, woNumber: "1001", site: "SITE-A", type: "PM", dispatcherId: "10", dispatcherName: "Alex", scheduledOn: "2026-07-16", completedDate: "", targetWeek: "", dayGroup: "2026-07-16", dayLabel: "Thu", location: "Main", locationId: 5, pm: "Plumbing", serviceNotes: "", extraServices: [], vendorId: "v1", company: "Acme", tech: "Sam", techPhone: "", apptStart: "", apptEnd: "", apptTime: "09:00", status: "Incomplete", docStatus: "", pocName: "", pocPhone: "", pocNotes: "", dueDate: "2026-07-20", rescheduleCount: 0, carriedOver: 0, originalWeek: "", originalDate: "", isPastDue: false, scheduleWeekOnly: false, mediaCount: 0, title: "", priority: "", primaryDispatchId: null, rowVersion: "rv1", dispatchRowVersion: "", flagColor: null, ...overrides, }; } describe("slide-over failed-save baseline contract", () => { it("stays dirty vs frozen baseline after optimistic parent absorbs the edit", () => { const baseline = row({ woNumber: "1001" }); const draft = row({ woNumber: "2002" }); const optimisticParent = row({ woNumber: "2002" }); const result = afterFailedOptimisticSave({ baseline, draft, optimisticParent, rolledBackParent: baseline, }); // Bug the review caught: comparing against optimistic parent clears dirty. expect(result.dirtyAgainstOptimistic).toBe(false); expect(result.dirtyAgainstBaseline).toBe(true); expect(result.dirtyAgainstRolledBack).toBe(true); expect(result.canRetry).toBe(true); expect(result.retryPatch).toEqual({ woNumber: "2002" }); }); });