// lib/config/validateEnv.test.js import { describe, it, expect } from "vitest"; import { validateEnv, MIN_SESSION_SECRET_LENGTH } from "./validateEnv.js"; function validSecret() { return "x".repeat(MIN_SESSION_SECRET_LENGTH); } describe("validateEnv", () => { it("returns normalized config for a valid env", () => { const cfg = validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/niederlassungen/", PORT: "3000", }); expect(cfg.mongodbUri).toBe("mongodb://localhost:27017/rhl"); expect(cfg.sessionSecret).toBe(validSecret()); expect(cfg.nasRootPath).toBe("/mnt/niederlassungen"); expect(cfg.nodeEnv).toBe("development"); expect(cfg.port).toBe(3000); }); it("accepts optional SESSION_COOKIE_SECURE=false", () => { expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/niederlassungen", NODE_ENV: "production", SESSION_COOKIE_SECURE: "false", }) ).not.toThrow(); }); it("rejects invalid SESSION_COOKIE_SECURE values", () => { expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/niederlassungen", SESSION_COOKIE_SECURE: "maybe", }) ).toThrow(/SESSION_COOKIE_SECURE/i); }); it("throws with a clear error if required vars are missing", () => { try { validateEnv({}); throw new Error("Expected validateEnv to throw"); } catch (err) { expect(err.code).toBe("ENV_INVALID"); expect(err.missing).toEqual([ "MONGODB_URI", "SESSION_SECRET", "NAS_ROOT_PATH", ]); expect(String(err.message)).toContain( "Missing required environment variables:" ); } }); it("rejects invalid MONGODB_URI schemes", () => { expect(() => validateEnv({ MONGODB_URI: "http://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/niederlassungen", NODE_ENV: "production", }) ).toThrow(/MONGODB_URI/i); }); it("rejects too-short SESSION_SECRET", () => { expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: "short-secret", NAS_ROOT_PATH: "/mnt/niederlassungen", }) ).toThrow(/SESSION_SECRET/i); }); it("rejects placeholder-like SESSION_SECRET even if long enough", () => { const secret = `change-me-${"x".repeat(64)}`; expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: secret, NAS_ROOT_PATH: "/mnt/niederlassungen", }) ).toThrow(/placeholder/i); }); it("rejects NAS_ROOT_PATH that is not absolute", () => { expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "mnt/niederlassungen", }) ).toThrow(/NAS_ROOT_PATH/i); }); it('rejects NAS_ROOT_PATH containing ".." segments', () => { expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/../etc", }) ).toThrow(/NAS_ROOT_PATH/i); }); it("rejects invalid NODE_ENV values", () => { expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/niederlassungen", NODE_ENV: "staging", }) ).toThrow(/NODE_ENV/i); }); it("rejects invalid PORT values", () => { expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/niederlassungen", PORT: "70000", }) ).toThrow(/PORT/i); expect(() => validateEnv({ MONGODB_URI: "mongodb://localhost:27017/rhl", SESSION_SECRET: validSecret(), NAS_ROOT_PATH: "/mnt/niederlassungen", PORT: "abc", }) ).toThrow(/PORT/i); }); });