import { describe, expect, it } from "vitest"; import { previewBounds, previewLoadError, previewShortcut, previewUrl, } from "./browser-preview-policy.js"; describe("previewUrl", () => { it("accepts only http(s) without credentials", () => { expect(previewUrl("http://localhost:5173")).toBe("http://localhost:5173/"); expect(previewUrl("https://example.com/a?b=1")).toBe("https://example.com/a?b=1"); for (const value of [ "file:///etc/hosts", "javascript:alert(1)", "chrome://settings", "https://user:fake-password@example.com", "not a url", 42, `https://example.com/${"a".repeat(9000)}`, ]) { expect(previewUrl(value)).toBeNull(); } }); }); describe("previewBounds", () => { const content = { width: 1200, height: 800 }; it("rounds and applies the app zoom factor", () => { expect(previewBounds({ x: 800.4, y: 40.6, width: 399.5, height: 700 }, content)).toEqual({ x: 800, y: 41, width: 400, height: 700, }); expect(previewBounds({ x: 100, y: 10, width: 200, height: 100 }, content, 1.25)).toEqual({ x: 125, y: 13, width: 250, height: 125, }); }); it("clamps to the window and rejects empty or malformed rectangles", () => { expect(previewBounds({ x: -50, y: -10, width: 5000, height: 5000 }, content)).toEqual({ x: 0, y: 0, width: 1200, height: 800, }); expect(previewBounds({ x: 1300, y: 0, width: 100, height: 100 }, content)).toBeNull(); expect(previewBounds({ x: 0, y: 0, width: 0, height: 100 }, content)).toBeNull(); expect(previewBounds({ x: "1", y: 0, width: 1, height: 1 }, content)).toBeNull(); expect(previewBounds({ x: Number.NaN, y: 0, width: 1, height: 1 }, content)).toBeNull(); expect(previewBounds(null, content)).toBeNull(); }); }); describe("previewShortcut", () => { const key = (overrides: Partial[0]>) => ({ type: "keyDown", key: "r", control: false, meta: false, alt: false, shift: false, ...overrides, }); it("maps platform browser shortcuts", () => { expect(previewShortcut(key({ meta: true }), "darwin")).toBe("reload"); expect(previewShortcut(key({ meta: true, shift: true, key: "R" }), "darwin")).toBe( "hard-reload", ); expect(previewShortcut(key({ control: true }), "linux")).toBe("reload"); expect(previewShortcut(key({ meta: true, key: "[" }), "darwin")).toBe("back"); expect(previewShortcut(key({ alt: true, key: "ArrowRight" }), "win32")).toBe("forward"); expect(previewShortcut(key({ key: "F12" }), "linux")).toBe("devtools"); expect(previewShortcut(key({ key: "F5" }), "win32")).toBe("reload"); }); it("leaves typing alone", () => { expect(previewShortcut(key({}), "darwin")).toBeNull(); expect(previewShortcut(key({ control: true }), "darwin")).toBeNull(); expect(previewShortcut(key({ type: "keyUp", meta: true }), "darwin")).toBeNull(); expect(previewShortcut(key({ key: "ArrowLeft" }), "linux")).toBeNull(); }); }); describe("previewLoadError", () => { it("ignores superseded navigations", () => { expect(previewLoadError(-3, "ERR_ABORTED")).toBeNull(); expect(previewLoadError(-102, "ERR_CONNECTION_REFUSED")).toBe("ERR_CONNECTION_REFUSED"); }); });