import { describe, expect, test } from "vitest"; import { getAbsoluteApiUrl, getAbsoluteUrl, getBaseURL, getWebhooksUrl } from "./url.server"; const productionEnv = { NODE_ENV: "production", APP_NAME: "Production App", DATABASE_URL: "postgres://example.invalid/app", APP_BASE_DOMAIN: "example.com", WEB_APP_HOST: "app.example.com", ADMIN_APP_HOST: "admin.example.com", API_HOST: "api.example.com", // Production secret-strength hardening (packages/config/src/web.ts) requires // >= 32 chars and SESSION_SECRET != CRYPTO_SECRET in production. These are // length-valid, distinct test placeholders so the URL helpers can load config. SESSION_SECRET: "session-secret-value-0123456789abcdef", CRYPTO_SECRET: "crypto-secret-value-fedcba9876543210", API_ACCESS_TOKEN: "api-access-token-value-0123456789abcdef", JWT_SECRET: "jwt-secret-value-0123456789abcdef0123", }; const testEnv = { APP_NAME: "Test App", DATABASE_URL: "postgres://example.invalid/app", SESSION_SECRET: "session-secret-value", CRYPTO_SECRET: "crypto-secret-value", API_ACCESS_TOKEN: "api-access-token-value", JWT_SECRET: "jwt-secret-value", }; describe("url.server", () => { test("keeps production base URLs on https even when forwarded protocol is http", () => { const request = new Request("http://internal.local/dashboard", { headers: { host: "internal.local", "x-forwarded-host": "app.example.com", "x-forwarded-proto": "http", }, }); expect(getBaseURL(request, { env: productionEnv })).toBe("https://app.example.com"); }); test("uses forwarded protocol outside production when injected env is not development", () => { const request = new Request("http://internal.local/dashboard", { headers: { host: "internal.local", "x-forwarded-host": "preview.example.com", "x-forwarded-proto": "https", }, }); expect(getBaseURL(request, { env: { ...testEnv, NODE_ENV: "test" } })).toBe("https://preview.example.com"); }); test("forces http in development mode through injected env", () => { const request = new Request("https://localhost:3000/dashboard", { headers: { host: "localhost:3000", "x-forwarded-host": "localhost:3000", "x-forwarded-proto": "https", }, }); expect(getBaseURL(request, { env: { ...testEnv, NODE_ENV: "development" } })).toBe("http://localhost:3000"); }); test("uses webhook override from injected env", () => { const request = new Request("https://app.example.com/dashboard"); expect(getWebhooksUrl(request, { env: { ...productionEnv, WEBHOOKS_URL: "https://hooks.example.com/webhooks" } })).toBe("https://hooks.example.com/webhooks"); }); test("generates absolute versioned API URLs from routing config", () => { const request = new Request("https://app.example.com/dashboard"); expect(getAbsoluteApiUrl(request, "billing/events", { env: productionEnv })).toBe("https://api.example.com/v1/billing/events"); expect(getAbsoluteApiUrl(request, "/v1/health", { env: productionEnv })).toBe("https://api.example.com/v1/health"); expect(getAbsoluteApiUrl(request, "/api/v1/health", { env: productionEnv })).toBe("https://api.example.com/v1/health"); expect(getAbsoluteApiUrl(request, "/api/v1?active=true", { env: productionEnv })).toBe("https://api.example.com/v1?active=true"); expect(getAbsoluteApiUrl(request, "/v1#docs", { env: productionEnv })).toBe("https://api.example.com/v1#docs"); }); test("builds host-aware absolute URLs from the current canonical request host", () => { expect(getAbsoluteUrl(new Request("https://admin.example.com/settings"), "/settings/profile", { env: productionEnv })).toBe( "https://admin.example.com/settings/profile" ); expect(getAbsoluteUrl(new Request("https://example.com/acme/settings"), "/acme/dashboard", { env: productionEnv })).toBe( "https://app.example.com/acme/dashboard" ); }); test("builds public app URLs on the web host even from admin requests", () => { const adminRequest = new Request("https://admin.example.com/settings"); expect(getAbsoluteUrl(adminRequest, "/invitation/invite_token", { env: productionEnv })).toBe("https://app.example.com/invitation/invite_token"); expect(getAbsoluteUrl(adminRequest, "/docs/en", { env: productionEnv })).toBe("https://app.example.com/docs/en"); expect(getAbsoluteUrl(adminRequest, "/healthcheck", { env: productionEnv })).toBe("https://app.example.com/healthcheck"); expect(getAbsoluteUrl(adminRequest, "/readyz", { env: productionEnv })).toBe("https://app.example.com/readyz"); expect(getAbsoluteUrl(adminRequest, "/swagger", { env: productionEnv })).toBe("https://app.example.com/swagger"); expect(getAbsoluteUrl(adminRequest, "/v1/health", { env: productionEnv })).toBe("https://api.example.com/v1/health"); }); test("normalizes absolute URL inputs to same-origin canonical paths", () => { const adminRequest = new Request("https://admin.example.com/settings"); expect(getAbsoluteUrl(adminRequest, "https://external.example/login?redirectTo=%2Fdashboard#top", { env: productionEnv })).toBe( "https://app.example.com/login?redirectTo=%2Fdashboard#top" ); expect(getAbsoluteUrl(adminRequest, "//external.example/v1/health", { env: productionEnv })).toBe("https://api.example.com/v1/health"); }); });