import { describe, expect, test } from "vitest"; import type { PartialHeadplaneConfigWithPaths } from "~/server/config/config-schema"; import { ConfigError } from "~/server/config/error"; import { loadConfigKeyPaths } from "~/server/config/load"; import { createFakeFile } from "../setup/overlay-fs"; describe("Configuration secret path handling", () => { test("should correctly substitute server.cookie_secret", async () => { createFakeFile("/secrets/cookie_secret.txt", "supersecretcookievalue"); const config = { server: { cookie_secret_path: "/secrets/cookie_secret.txt", }, } as PartialHeadplaneConfigWithPaths; await loadConfigKeyPaths(config); expect(config.server?.cookie_secret).toBe("supersecretcookievalue"); }); test("should throw error for missing secret file", async () => { const config = { server: { cookie_secret_path: "/secrets/missing_cookie_secret.txt", }, } as PartialHeadplaneConfigWithPaths; await expect(loadConfigKeyPaths(config)).rejects.toMatchObject( ConfigError.from("MISSING_SECRET_FILE", { pathKey: "server.cookie_secret_path", filePath: "/secrets/missing_cookie_secret.txt", }), ); }); test("should throw error for conflicting secret path and field", async () => { const config = { server: { cookie_secret: "explicitsecretvalue", cookie_secret_path: "/secrets/cookie_secret.txt", }, } as PartialHeadplaneConfigWithPaths; await expect(loadConfigKeyPaths(config)).rejects.toMatchObject( ConfigError.from("CONFLICTING_SECRET_PATH_FIELD", { fieldName: "server.cookie_secret", }), ); }); test("should correctly interpolate env vars in secret paths", async () => { process.env.HP_TEST_COOKIE_SECRET_FILE = "cookie_secret.txt"; createFakeFile(`/secrets/${process.env.HP_TEST_COOKIE_SECRET_FILE}`, "envvarsecretvalue"); const config = { server: { cookie_secret_path: "/secrets/${HP_TEST_COOKIE_SECRET_FILE}", }, } as PartialHeadplaneConfigWithPaths; await loadConfigKeyPaths(config); expect(config.server?.cookie_secret).toBe("envvarsecretvalue"); }); test("should throw error for missing interpolated env var in secret path", async () => { const config = { server: { cookie_secret_path: "/secrets/${MISSING_ENV_VAR}", }, } as PartialHeadplaneConfigWithPaths; await expect(loadConfigKeyPaths(config)).rejects.toMatchObject( ConfigError.from("MISSING_INTERPOLATION_VARIABLE", { pathKey: "server.cookie_secret_path", variableName: "MISSING_ENV_VAR", }), ); }); });