import { describe, expect, it } from "vitest"; import { loadRuntimeConfig } from "../../src/bootstrap/load-runtime-config.ts"; import { validateRuntimeConfig } from "../../src/bootstrap/runtime-config-schema.ts"; import { assertSafeConfigNames } from "../../src/contracts/env.ts"; const validConfig = { APP_ENV: "local", API_BASE_URL: "http://localhost:8080/", REQUEST_TIMEOUT_MS: 10_000, MAX_RETRY_ATTEMPTS: 2, TELEMETRY_ENABLED: false, AUTH_MODE: "external", CONFIG_SCHEMA_VERSION: "2.0", RELEASE_MANIFEST_URL: "/release-manifest.json", BUILD_ID: "build-a", }; const validV1Config = { ...validConfig, CONFIG_SCHEMA_VERSION: "1", API_CONTRACT_VERSION: "1.4.0", }; describe("runtime configuration boundary", () => { it.each([ [{ ...validConfig, API_BASE_URL: undefined }, "required key"], [{ ...validConfig, REQUEST_TIMEOUT_MS: 0 }, "integer range"], [{ ...validConfig, MAX_RETRY_ATTEMPTS: 3 }, "retry cap"], [{ ...validConfig, TELEMETRY_ENABLED: "false" }, "ambiguous boolean"], [{ ...validConfig, CONFIG_SCHEMA_VERSION: "next" }, "version"], [ { ...validConfig, API_CONTRACT_VERSION: "1" }, "§5.1 scalar contract version is removed from V2", ], [ { ...validConfig, API_BASE_URL: "http://localhost:8080/api" }, "§6.2 base URL path must end with /", ], [ { ...validConfig, API_BASE_URL: "http://localhost:8080/#frag" }, "§6.2 hash in base URL", ], [ { ...validConfig, API_BASE_URL: "http://user:pw@localhost:8080/" }, "§6.2 credentials in URL", ], [ { ...validConfig, RELEASE_MANIFEST_URL: "/a/../b.json" }, "§6.2 dot segment traversal", ], [ { ...validConfig, RELEASE_MANIFEST_URL: "/manifest.json?v=1" }, "§6.2 query in manifest URL", ], [{ ...validConfig, UNKNOWN_KEY: true }, "unknown key"], ])("rejects invalid config: %s (%s)", (candidate, _reason) => { void _reason; expect(validateRuntimeConfig(candidate).success).toBe(false); }); it("rejects secret-like names before schema validation", () => { expect(() => assertSafeConfigNames({ CLIENT_SECRET: "not-safe" })).toThrow( "Forbidden client configuration key", ); }); it("allows demo authentication only for local runtime configuration", () => { expect( validateRuntimeConfig({ ...validConfig, AUTH_MODE: "demo" }).success, ).toBe(true); expect( validateRuntimeConfig({ ...validConfig, APP_ENV: "production", API_BASE_URL: "https://api.example.test/", AUTH_MODE: "demo", }).success, ).toBe(false); }); it("accepts only the explicitly supported V1 and V2 boot versions", () => { expect(validateRuntimeConfig(validV1Config)).toMatchObject({ success: true, schema: "V1", }); expect(validateRuntimeConfig(validConfig)).toMatchObject({ success: true, schema: "V2", }); for (const version of ["0", "1.0", "2.0.1", "3.0"]) { expect( validateRuntimeConfig({ ...validV1Config, CONFIG_SCHEMA_VERSION: version, }).success, ).toBe(false); } }); it.each([ "file:///tmp/api/", "data:text/plain,/", "blob:https://example.test/00000000-0000-0000-0000-000000000000", ])("rejects a non-HTTP API endpoint in local mode: %s", (API_BASE_URL) => { expect(validateRuntimeConfig({ ...validConfig, API_BASE_URL }).success).toBe( false, ); }); it.each(["file:///tmp/telemetry", "data:text/plain,telemetry"])( "rejects a non-HTTP telemetry endpoint in local mode: %s", (TELEMETRY_ENDPOINT) => { expect( validateRuntimeConfig({ ...validConfig, TELEMETRY_ENABLED: true, TELEMETRY_ENDPOINT, }).success, ).toBe(false); }, ); it("validates a fetched config under the 500ms budget excluding network", async () => { let current = 100; const result = await loadRuntimeConfig({ buildConfig: { buildId: "build-a", commitSha: "local", routerBasePath: "/", runtimeConfigUrl: "/config.json", }, fetcher: async () => new Response(JSON.stringify(validConfig), { headers: { "content-type": "application/json" }, }), now: () => (current += 2), }); expect(result.validationDurationMs).toBeLessThanOrEqual(500); expect(result.config.API_BASE_URL).toBe("http://localhost:8080/"); expect(result.configSchema).toBe("V2"); expect(result.config.CAPABILITY_OVERRIDES.SERVICE_WORKER).toBe("DEFAULT"); }); it("does not include network acquisition in validationDurationMs", async () => { let current = 0; const result = await loadRuntimeConfig({ buildConfig: { buildId: "build-a", commitSha: "local", routerBasePath: "/", runtimeConfigUrl: "/config.json", }, fetcher: async () => { current = 10_000; return new Response(JSON.stringify(validConfig), { headers: { "content-type": "application/json" }, }); }, now: () => current, }); expect(result.validationDurationMs).toBe(0); }); it("accepts TECH_LOG_STUDIO_SOURCE and defaults it to MOCK", () => { const defaulted = validateRuntimeConfig(validConfig); expect(defaulted.success).toBe(true); if (defaulted.success) { expect(defaulted.data.TECH_LOG_STUDIO_SOURCE).toBe("MOCK"); } const explicit = validateRuntimeConfig({ ...validConfig, TECH_LOG_STUDIO_SOURCE: "HTTP", }); expect(explicit.success).toBe(true); if (explicit.success) { expect(explicit.data.TECH_LOG_STUDIO_SOURCE).toBe("HTTP"); } expect( validateRuntimeConfig({ ...validConfig, TECH_LOG_STUDIO_SOURCE: "LIVE", }).success, ).toBe(false); // A V1 document has no such key; normalization must still land on MOCK. expect(validateRuntimeConfig(validV1Config)).toMatchObject({ success: true, data: { TECH_LOG_STUDIO_SOURCE: "MOCK" }, }); }); it("returns only safe boot fields on failure", async () => { await expect( loadRuntimeConfig({ buildConfig: { buildId: "build-a", commitSha: "local", routerBasePath: "/", runtimeConfigUrl: "/config.json", }, fetcher: async () => new Response("{", { headers: { "content-type": "application/json" }, }), }), ).rejects.toMatchObject({ safe: { kind: "BOOT_CONFIG_FAILURE", buildId: "build-a", }, }); }); });