47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
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);
|
|
});
|