config.unit.test.ts
⎇
Raw
1import { describe, expect, test } from "bun:test";
2
3// config.ts reads process.env once at import time, so these run the same
4// parsing logic against a fresh module instance per case.
5async function loadConfig(env: Record<string, string>) {
6 const saved: Record<string, string | undefined> = {};
7 for (const k of Object.keys(env)) {
8 saved[k] = process.env[k];
9 process.env[k] = env[k];
10 }
11 try {
12 // Cache-bust so the module body re-runs against the patched env.
13 const mod = await import(`../src/config.ts?t=${Math.random()}`);
14 return mod.default as typeof import("../src/config.ts").default;
15 } finally {
16 for (const [k, v] of Object.entries(saved)) {
17 if (v === undefined) delete process.env[k];
18 else process.env[k] = v;
19 }
20 }
21}
22
23describe("config env parsing", () => {
24 test("unset falls back to the default", async () => {
25 const c = await loadConfig({});
26 expect(c.MAX_TITLE_BYTES).toBe(500);
27 expect(c.CI_MAX_HISTORY).toBe(50);
28 });
29
30 test("empty string falls back to the default", async () => {
31 const c = await loadConfig({ MAX_TITLE_BYTES: "" });
32 expect(c.MAX_TITLE_BYTES).toBe(500);
33 });
34
35 test("garbage falls back to the default", async () => {
36 const c = await loadConfig({ MAX_TITLE_BYTES: "abc" });
37 expect(c.MAX_TITLE_BYTES).toBe(500);
38 });
39
40 test("a valid number is used", async () => {
41 const c = await loadConfig({ MAX_TITLE_BYTES: "120" });
42 expect(c.MAX_TITLE_BYTES).toBe(120);
43 });
44
45 test("explicit 0 is honoured, not replaced by the default", async () => {
46 expect((await loadConfig({ MAX_RENDER_BYTES: "0" })).MAX_RENDER_BYTES).toBe(0);
47 expect((await loadConfig({ INLINE_MAX_BYTES: "0" })).INLINE_MAX_BYTES).toBe(0);
48 expect((await loadConfig({ CI_MAX_HISTORY: "0" })).CI_MAX_HISTORY).toBe(0);
49 });
50
51 test("BASE_URL default tracks PORT", async () => {
52 const c = await loadConfig({ PORT: "8080" });
53 expect(c.PORT).toBe(8080);
54 expect(c.BASE_URL).toBe("http://localhost:8080");
55 expect(c.PUBLIC_ORIGIN).toBe("http://localhost:8080");
56 expect(c.PUBLIC_HTTPS).toBe(false);
57 });
58
59 test("an https BASE_URL sets the derived origin fields", async () => {
60 const c = await loadConfig({ BASE_URL: "https://forge.example.com" });
61 expect(c.PUBLIC_HTTPS).toBe(true);
62 expect(c.PUBLIC_ORIGIN).toBe("https://forge.example.com");
63 expect(c.COMMITTER_EMAIL).toContain("@forge.example.com");
64 });
65});
66