import { afterEach, describe, expect, it, vi } from "vitest"; import { buildAdminUrl, buildSiteUrl, fromDevelopmentAdminPath, getAdminAppPath, getAdminBaseUrl, getAdminHost, getRequestHostname, getSiteBaseUrl, getSiteHost, hasDedicatedAdminHost, INTERNAL_ADMIN_PREFIX, isAdminHost, isDevelopmentAdminPath, isInternalAdminPath, isLegacyAdminPath, toInternalAdminPath, } from "@/lib/admin-routing"; afterEach(() => { vi.unstubAllEnvs(); }); describe("getRequestHostname", () => { it("prefers the first non-empty candidate", () => { expect(getRequestHostname("root.mohfarawati.de", "internal")).toBe("root.mohfarawati.de"); }); it("strips ports and takes the first comma-separated proxy value", () => { expect(getRequestHostname(undefined, "root.mohfarawati.de:443, proxy")).toBe("root.mohfarawati.de"); }); it("lowercases the hostname", () => { expect(getRequestHostname("ROOT.MohFarawati.de")).toBe("root.mohfarawati.de"); }); it("falls back to empty string when nothing matches", () => { expect(getRequestHostname(undefined, null, "")).toBe(""); }); }); describe("host configuration", () => { it("defaults admin and site hosts", () => { expect(getAdminHost()).toBe("root.mohfarawati.de"); expect(getSiteHost()).toBe("mohfarawati.de"); expect(hasDedicatedAdminHost()).toBe(true); }); it("reads ADMIN_HOST override and normalizes case/whitespace", () => { vi.stubEnv("ADMIN_HOST", " Admin.Example.COM "); expect(getAdminHost()).toBe("admin.example.com"); }); it("derives the site host from NEXT_PUBLIC_SITE_URL", () => { vi.stubEnv("NEXT_PUBLIC_SITE_URL", "https://example.org/some/path"); expect(getSiteHost()).toBe("example.org"); }); it("hasDedicatedAdminHost is false when admin and site hosts match", () => { vi.stubEnv("ADMIN_HOST", "example.com"); vi.stubEnv("NEXT_PUBLIC_SITE_URL", "https://example.com"); expect(hasDedicatedAdminHost()).toBe(false); }); it("isAdminHost compares against the configured admin host", () => { expect(isAdminHost("root.mohfarawati.de")).toBe(true); expect(isAdminHost("mohfarawati.de")).toBe(false); }); }); describe("path predicates", () => { it("recognizes legacy /root paths", () => { expect(isLegacyAdminPath("/root")).toBe(true); expect(isLegacyAdminPath("/root/portfolio")).toBe(true); expect(isLegacyAdminPath("/rooting")).toBe(false); expect(isLegacyAdminPath("/")).toBe(false); }); it("recognizes development /root paths", () => { expect(isDevelopmentAdminPath("/root")).toBe(true); expect(isDevelopmentAdminPath("/root/media")).toBe(true); expect(isDevelopmentAdminPath("/rootx")).toBe(false); }); it("recognizes internal admin paths", () => { expect(isInternalAdminPath(INTERNAL_ADMIN_PREFIX)).toBe(true); expect(isInternalAdminPath(`${INTERNAL_ADMIN_PREFIX}/smtp`)).toBe(true); expect(isInternalAdminPath("/admin")).toBe(false); }); }); describe("path translation", () => { it("maps public paths to internal admin paths", () => { expect(toInternalAdminPath("/")).toBe(INTERNAL_ADMIN_PREFIX); expect(toInternalAdminPath("/portfolio")).toBe(`${INTERNAL_ADMIN_PREFIX}/portfolio`); expect(toInternalAdminPath("portfolio")).toBe(`${INTERNAL_ADMIN_PREFIX}/portfolio`); }); it("strips the dev /root prefix", () => { expect(fromDevelopmentAdminPath("/root")).toBe("/"); expect(fromDevelopmentAdminPath("/root/portfolio")).toBe("/portfolio"); expect(fromDevelopmentAdminPath("/portfolio")).toBe("/portfolio"); }); }); describe("getAdminAppPath", () => { it("returns bare paths when a dedicated admin host exists", () => { // default env: admin host != site host -> dedicated host branch expect(getAdminAppPath("/")).toBe("/"); expect(getAdminAppPath("/smtp")).toBe("/smtp"); }); it("uses the /root dev prefix when no dedicated host and not production", () => { vi.stubEnv("ADMIN_HOST", "example.com"); vi.stubEnv("NEXT_PUBLIC_SITE_URL", "https://example.com"); vi.stubEnv("NODE_ENV", "development"); expect(getAdminAppPath("/")).toBe("/root"); expect(getAdminAppPath("/portfolio")).toBe("/root/portfolio"); }); it("returns bare paths in production even without a dedicated host", () => { vi.stubEnv("ADMIN_HOST", "example.com"); vi.stubEnv("NEXT_PUBLIC_SITE_URL", "https://example.com"); vi.stubEnv("NODE_ENV", "production"); expect(getAdminAppPath("/portfolio")).toBe("/portfolio"); }); }); describe("url builders", () => { it("builds admin urls from NEXT_PUBLIC_ADMIN_URL", () => { expect(getAdminBaseUrl()).toBe("https://root.mohfarawati.de"); expect(buildAdminUrl("/smtp")).toBe("https://root.mohfarawati.de/smtp"); }); it("trims trailing slashes from configured base urls", () => { vi.stubEnv("NEXT_PUBLIC_ADMIN_URL", "https://admin.example.com/"); expect(getAdminBaseUrl()).toBe("https://admin.example.com"); }); it("builds site urls from NEXT_PUBLIC_SITE_URL", () => { expect(getSiteBaseUrl()).toBe("https://mohfarawati.de"); expect(buildSiteUrl("/about")).toBe("https://mohfarawati.de/about"); expect(buildSiteUrl("/")).toBe("https://mohfarawati.de/"); }); });