import { buildFaviconUrl, customIconId, customIconRef, isCustomIconRef, resolveIcon, } from "../favicon"; import { __resetApiConfigStoreForTests, configureApi } from "../api-config"; beforeEach(() => { __resetApiConfigStoreForTests(); configureApi({ apiBaseUrl: "https://api.example.com", storagePrefix: "demo" }); }); describe("buildFaviconUrl", () => { it("returns null for missing input", () => { expect(buildFaviconUrl(null)).toBeNull(); expect(buildFaviconUrl(undefined)).toBeNull(); expect(buildFaviconUrl("")).toBeNull(); expect(buildFaviconUrl(" ")).toBeNull(); }); it("promotes bare hostnames to https", () => { const url = buildFaviconUrl("github.com"); expect(url).toContain("https%3A%2F%2Fgithub.com"); }); it("preserves explicit http URLs", () => { const url = buildFaviconUrl("http://example.com"); expect(url).toContain("http%3A%2F%2Fexample.com"); }); it("rejects non-http(s) schemes", () => { expect(buildFaviconUrl("ftp://x.example.com")).toBeNull(); expect(buildFaviconUrl("file:///etc/passwd")).toBeNull(); }); it("uses the configured base URL", () => { expect(buildFaviconUrl("github.com")).toMatch(/^https:\/\/api\.example\.com\/favicon\?/); }); it("respects a custom faviconPath", () => { expect(buildFaviconUrl("github.com", "/icons/proxy")).toMatch( /^https:\/\/api\.example\.com\/icons\/proxy\?/ ); }); }); describe("customIconRef helpers", () => { it("round-trips a custom upload reference", () => { expect(customIconRef("abc-123")).toBe("custom:abc-123"); expect(isCustomIconRef("custom:abc-123")).toBe(true); expect(customIconId("custom:abc-123")).toBe("abc-123"); }); it("rejects non-custom strings", () => { expect(isCustomIconRef("https://example.com/favicon.png")).toBe(false); expect(customIconId(null)).toBeNull(); expect(customIconId("")).toBeNull(); expect(customIconId("custom:")).toBeNull(); }); }); describe("resolveIcon", () => { it("prefers a custom upload over a site URL", () => { expect(resolveIcon({ iconUrl: "custom:42", siteUrl: "github.com" })).toEqual({ kind: "upload", uploadId: "42", }); }); it("passes through a literal icon URL", () => { const r = resolveIcon({ iconUrl: "https://cdn.example.com/icon.png" }); expect(r).toEqual({ kind: "url", uri: "https://cdn.example.com/icon.png" }); }); it("derives a favicon URL from the site when no iconUrl is set", () => { const r = resolveIcon({ siteUrl: "github.com" }); expect(r.kind).toBe("url"); if (r.kind === "url") { expect(r.uri).toMatch(/api\.example\.com\/favicon\?/); } }); it("returns kind=none when neither resolves", () => { expect(resolveIcon({})).toEqual({ kind: "none" }); }); });