import { expect, test } from "bun:test"; import { gatewayWebSocketOriginAllowed } from "../src/gateway.ts"; const target = { name: "web", origin: "http://127.0.0.1:3101", domains: ["localhost", "web.localhost"], publicOrigin: "http://localhost:3000", } as any; function upgrade(origin: string, host: string): Request { return new Request("http://" + host + "/__wrnexus/hmr", { headers: { origin, host, upgrade: "websocket" }, }); } test("allows an upgrade from the app's primary domain", () => { expect( gatewayWebSocketOriginAllowed(upgrade("http://localhost:3000", "localhost:3000"), target, []), ).toBe(true); }); test("allows an upgrade from a secondary domain on a non-default port", () => { // publicOrigin is built from domains[0], so a browser on web.localhost falls // through to the domain list — where the origin host still carries :3000 and // the configured domain does not. That mismatch denied every HMR socket on // any domain but the first, leaving the client reconnecting forever. expect( gatewayWebSocketOriginAllowed( upgrade("http://web.localhost:3000", "web.localhost:3000"), target, [], ), ).toBe(true); }); test("still denies an unrelated origin", () => { expect( gatewayWebSocketOriginAllowed( upgrade("http://evil.example:3000", "web.localhost:3000"), target, [], ), ).toBe(false); }); test("still denies a lookalike suffix domain", () => { expect( gatewayWebSocketOriginAllowed( upgrade("http://notweb.localhost:3000", "web.localhost:3000"), target, [], ), ).toBe(false); });