import { afterEach, describe, expect, it, vi } from "vitest"; import { hostForKnot, tryHostForKnot } from "#lib/api/_request.ts"; describe("hostForKnot", () => { it.each([ ["did:web:knot2.example.com", "knot2.example.com"], ["did:web:KNOT2.EXAMPLE.COM", "knot2.example.com"], ["did:web:knot.example.com%3A8443", "knot.example.com:8443"], ["did:web:knot.example.com%3a8443", "knot.example.com:8443"], ["did:web:localhost%3A3000", "localhost:3000"], ["knot2.example.com", "knot2.example.com"], ["knot.example.com:8443", "knot.example.com:8443"], ["localhost", "localhost"], ["localhost:3000", "localhost:3000"], ["127.0.0.1:8000", "127.0.0.1:8000"] ])("normalizes %s to %s", (input, expected) => { expect(hostForKnot(input)).toBe(expected); }); it.each([ "did:plc:iz6r437h6kndu44y7u7f7rly", "https://knot2.example.com", "knot2.example.com/path", "did:web:", "did:web:foo/bar", "did:web:knot.dev:8443", "garbage text", ":::", "", " ", "knot..dev", "-knot.dev", "knot.dev:99999", "knot.dev:0", "foo@bar.com" ])("rejects garbage %j", (input) => { expect(() => hostForKnot(input)).toThrow(); }); }); describe("hosts outside dev", () => { afterEach(() => vi.unstubAllEnvs()); it.each([ "localhost", "localhost:6555", "LOCALHOST:6555", "foo.localhost", "foo.local", "metadata.internal", "intranet", "127.0.0.1", "127.0.0.1:8000", "10.0.0.5", "169.254.169.254", "192.168.1.1:80", "2130706433", "0x7f000001", "0x7f.1", "017700000001", "127.1", "did:web:localhost%3A6555", "did:web:169.254.169.254", "[::1]", "[::1]:80", "::1" ])("refuses %s", (input) => { vi.stubEnv("DEV", false); expect(() => hostForKnot(input)).toThrow(); expect(tryHostForKnot(input)).toBeUndefined(); }); it.each([ ["spindle.example.com", "spindle.example.com"], ["spindle.tngl.boltless.dev:8443", "spindle.tngl.boltless.dev:8443"], ["did:web:knot1.tangled.sh", "knot1.tangled.sh"], ["a.b1", "a.b1"] ])("keeps %s", (input, expected) => { vi.stubEnv("DEV", false); expect(hostForKnot(input)).toBe(expected); }); it("allows loopback in dev", () => { vi.stubEnv("DEV", true); expect(hostForKnot("localhost:6555")).toBe("localhost:6555"); expect(hostForKnot("127.0.0.1:8000")).toBe("127.0.0.1:8000"); }); }); describe("tryHostForKnot", () => { it.each([ ["did:web:spindle.example.com", "spindle.example.com"], ["did:web:localhost%3A6555", "localhost:6555"], ["spindle.example.com", "spindle.example.com"], ["did:plc:abcdefghijklmnopqrstuvwx", undefined], ["did:web:bad%zz", undefined], ["did:web:a%3A1:path", undefined], ["evil.com/x", undefined], ["a@b", undefined], ["http://x", undefined], ["a b", undefined], ["", undefined], [undefined, undefined] ])("%s -> %s", (input, expected) => { expect(tryHostForKnot(input)).toBe(expected); }); });