shoc-frontend-new/src/test/app/(protected)/workorders/wizard-schedule-date-range.test.tsx
Arthur Bassi 3ed8600beb fix(work-orders): promote dated pre-schedule picks to Scheduled
Align create, wizard, and board status patches with AAP maybeAutoSchedule.
Include the previous status in audit copy when the API sends it.
2026-09-04 14:31:08 -03:00

114 lines
3.4 KiB
TypeScript

import { fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { WizardStepTypeSchedule } from "@/app/(protected)/workorders/_components/wizard/wizard-step-type-schedule";
import {
EMPTY_WIZARD_DRAFT,
type WorkOrderWizardDraft,
} from "@/domain/work-orders/types/work-order-wizard";
import { pad2, todayIso } from "@/domain/work-orders/utils/wizard-date-utils";
function baseDraft(overrides: Partial<WorkOrderWizardDraft> = {}): WorkOrderWizardDraft {
return { ...EMPTY_WIZARD_DRAFT, type: "PM", ...overrides };
}
function currentMonthIso(day: number): string {
const [y, m] = todayIso().split("-").map(Number);
return `${y}-${pad2(m)}-${pad2(day)}`;
}
async function openScheduleRangePicker() {
fireEvent.click(screen.getByRole("button", { name: /pick a date/i }));
const rangeTab = await screen.findByRole("button", { name: "Range" });
fireEvent.click(rangeTab);
}
describe("WizardStepTypeSchedule — Schedule On range selection", () => {
it("clicks start then end in order and submits schedMode range with matching dates", async () => {
const onUpdate = vi.fn();
const onPatch = vi.fn();
render(
<WizardStepTypeSchedule
draft={baseDraft()}
users={[]}
onUpdate={onUpdate}
onPatch={onPatch}
/>,
);
await openScheduleRangePicker();
const startIso = currentMonthIso(5);
const endIso = currentMonthIso(20);
fireEvent.click(screen.getByRole("button", { name: "5" }));
fireEvent.click(screen.getByRole("button", { name: "20" }));
fireEvent.click(screen.getByRole("button", { name: /^done$/i }));
expect(onPatch).toHaveBeenCalledWith({
scheduledOn: startIso,
scheduleEnd: endIso,
schedMode: "range",
scheduleWeekOnly: false,
targetWeek: "",
isAddOnOverride: false,
status: "Scheduled",
});
});
it("normalizes an out-of-order click (end clicked before start) into start<end on submission", async () => {
const onUpdate = vi.fn();
const onPatch = vi.fn();
render(
<WizardStepTypeSchedule
draft={baseDraft()}
users={[]}
onUpdate={onUpdate}
onPatch={onPatch}
/>,
);
await openScheduleRangePicker();
const laterIso = currentMonthIso(20);
const earlierIso = currentMonthIso(5);
// User clicks the later date first, then an earlier date — the field must
// normalize this into (start = earlier, end = later) before submission.
fireEvent.click(screen.getByRole("button", { name: "20" }));
fireEvent.click(screen.getByRole("button", { name: "5" }));
fireEvent.click(screen.getByRole("button", { name: /^done$/i }));
expect(onPatch).toHaveBeenCalledWith({
scheduledOn: earlierIso,
scheduleEnd: laterIso,
schedMode: "range",
scheduleWeekOnly: false,
targetWeek: "",
isAddOnOverride: false,
status: "Scheduled",
});
});
it("does not submit until both a start and end date are picked", async () => {
const onUpdate = vi.fn();
const onPatch = vi.fn();
render(
<WizardStepTypeSchedule
draft={baseDraft()}
users={[]}
onUpdate={onUpdate}
onPatch={onPatch}
/>,
);
await openScheduleRangePicker();
fireEvent.click(screen.getByRole("button", { name: "5" }));
expect(screen.getByRole("button", { name: /^done$/i })).toBeDisabled();
expect(onPatch).not.toHaveBeenCalled();
});
});