import { expect, test } from "bun:test"; import { Window } from "happy-dom"; import { mountUnsavedChangesGuard } from "../src/unsaved.ts"; test("unsaved guard protects unload and ordinary navigation, permits safe links, and cleans up", () => { const window = new Window({ url: "https://email.example.com/builder/one" }); const root = window.document.createElement("main"); window.document.body.append(root); let dirty = true, allow = false, confirmations = 0; const guard = mountUnsavedChangesGuard(root as unknown as HTMLElement, { hasUnsavedChanges: () => dirty, confirmLeave: () => { confirmations++; return allow; }, }); const unload = () => { const event = new window.Event("beforeunload", { cancelable: true }); window.dispatchEvent(event); return event.defaultPrevented; }; const click = (href: string, target = "") => { const link = window.document.createElement("a"); link.href = href; link.target = target; root.append(link); const event = new window.MouseEvent("click", { bubbles: true, cancelable: true }); link.dispatchEvent(event); return event.defaultPrevented; }; expect(unload()).toBe(true); expect(click("/builder/two")).toBe(true); expect(click("#content")).toBe(false); expect(click("/builder/two", "_blank")).toBe(false); expect(confirmations).toBe(1); allow = true; expect(click("/builder/two")).toBe(false); dirty = false; expect(unload()).toBe(false); guard.destroy(); guard.destroy(); dirty = true; expect(unload()).toBe(false); });