diff --git a/src/test/app/(protected)/workorders/save-existing-row-type.test.ts b/src/test/app/(protected)/workorders/save-existing-row-type.test.ts index 0ca3f3c9..86b6020c 100644 --- a/src/test/app/(protected)/workorders/save-existing-row-type.test.ts +++ b/src/test/app/(protected)/workorders/save-existing-row-type.test.ts @@ -42,6 +42,16 @@ describe("saveExistingRowType", () => { expect(onPatch.mock.calls[0]![2]).toBeUndefined(); }); + it("does not warn when moving between SEV 3–5", () => { + const onPatch = vi.fn(); + + saveExistingRowType(onPatch, { ...row, severity: 5 }, "Reactive", 3); + + expect(toastWarn).not.toHaveBeenCalled(); + expect(onPatch).toHaveBeenCalledWith(7, { type: "Reactive", severity: 3 }); + expect(onPatch.mock.calls[0]![2]).toBeUndefined(); + }); + it("does not warn when clearing severity on a PM correction", () => { const onPatch = vi.fn(); diff --git a/src/test/app/(protected)/workorders/severity-badge.test.tsx b/src/test/app/(protected)/workorders/severity-badge.test.tsx new file mode 100644 index 00000000..2beb69ef --- /dev/null +++ b/src/test/app/(protected)/workorders/severity-badge.test.tsx @@ -0,0 +1,47 @@ +import { render, screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { describe, expect, it, vi } from "vitest"; +import { SeverityBadge } from "@/app/(protected)/workorders/_components/list/table/cells/severity-badge"; + +describe("SeverityBadge", () => { + it("shows description, Accept/Respond deadline, and after-hours on hover", async () => { + const user = userEvent.setup(); + render(); + + await user.hover(screen.getByText("SEV 1")); + + const tooltip = await screen.findByRole("tooltip"); + expect(tooltip).toHaveTextContent( + "Business Critical Function Down · Accept: 15 min · Respond: 2 hrs · After hours: Yes", + ); + expect(tooltip).not.toHaveTextContent(/Quote|Tech Notes|Invoice|Turnaround/i); + + await user.unhover(screen.getByText("SEV 1")); + await waitFor(() => expect(screen.queryByRole("tooltip")).not.toBeInTheDocument()); + }); + + it("transcribes the SEV table row for the given severity", async () => { + const user = userEvent.setup(); + render(); + + await user.hover(screen.getByText("SEV 3")); + + expect(await screen.findByRole("tooltip")).toHaveTextContent( + "Group Productivity Impaired · Accept: 2 hrs · Respond: 8 hrs (next day if after hours) · After hours: Approval required", + ); + }); + + it("is a button only when it can reopen the severity control", async () => { + const onClick = vi.fn(); + const user = userEvent.setup(); + const { rerender } = render(); + expect(screen.queryByRole("button")).not.toBeInTheDocument(); + + rerender(); + const badge = screen.getByRole("button"); + expect(badge).toHaveTextContent("SEV 2"); + await user.click(badge); + + expect(onClick).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/test/domain/work-orders/utils/severity-escalation.test.ts b/src/test/domain/work-orders/utils/severity-escalation.test.ts index 812e40f9..22c2cc9a 100644 --- a/src/test/domain/work-orders/utils/severity-escalation.test.ts +++ b/src/test/domain/work-orders/utils/severity-escalation.test.ts @@ -18,6 +18,21 @@ describe("shouldAnnounceSeverityEscalation", () => { expect(shouldAnnounceSeverityEscalation(2, 3)).toBe(false); }); + it("announces when severity rises from SEV 3–5 into SEV 2", () => { + expect(shouldAnnounceSeverityEscalation(5, 2)).toBe(true); + expect(shouldAnnounceSeverityEscalation(4, 2)).toBe(true); + }); + + it("does not announce moves between SEV 3–5", () => { + expect(shouldAnnounceSeverityEscalation(5, 3)).toBe(false); + expect(shouldAnnounceSeverityEscalation(4, 3)).toBe(false); + expect(shouldAnnounceSeverityEscalation(3, 5)).toBe(false); + }); + + it("does not announce SEV 1 to SEV 2 (already critical)", () => { + expect(shouldAnnounceSeverityEscalation(1, 2)).toBe(false); + }); + it("does not announce SEV 2 to SEV 1 (already critical)", () => { expect(shouldAnnounceSeverityEscalation(2, 1)).toBe(false); });