config.test.js (3506B)
1 import test from 'node:test'; 2 import assert from 'node:assert/strict'; 3 import fs from 'node:fs/promises'; 4 import os from 'node:os'; 5 import path from 'node:path'; 6 import { loadConfig } from '../src/lib/config.js'; 7 8 async function withEnv(env, fn) { 9 const saved = {}; 10 for (const key of Object.keys(process.env)) { 11 if (key.startsWith('AUTH_')) { 12 saved[key] = process.env[key]; 13 delete process.env[key]; 14 } 15 } 16 Object.assign(process.env, env); 17 try { 18 return await fn(); 19 } finally { 20 for (const key of Object.keys(process.env)) { 21 if (key.startsWith('AUTH_')) delete process.env[key]; 22 } 23 Object.assign(process.env, saved); 24 } 25 } 26 27 async function inTempDir(fn) { 28 const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'auth-cfg-')); 29 const cwd = process.cwd(); 30 process.chdir(dir); 31 try { 32 return await fn(); 33 } finally { 34 process.chdir(cwd); 35 await fs.rm(dir, { recursive: true, force: true }); 36 } 37 } 38 39 test('sqlite defaults load without any configuration', async () => { 40 await inTempDir(() => 41 withEnv({}, () => { 42 const cfg = loadConfig(); 43 assert.equal(cfg.database.dialect, 'sqlite'); 44 assert.equal(cfg.database.path, './data/system.sqlite'); 45 assert.equal(cfg.database.realms, './data/realms'); 46 }) 47 ); 48 }); 49 50 test('an explicit null database path is rejected', async () => { 51 await inTempDir(async () => { 52 await fs.writeFile('auth.yaml', 'database:\n path: null\n'); 53 await withEnv({}, () => { 54 assert.throws(() => loadConfig(), /database\.path/); 55 }); 56 }); 57 }); 58 59 test('sqlite configuration loads with both paths', async () => { 60 await inTempDir(() => 61 withEnv( 62 { 63 AUTH_DATABASE_DIALECT: 'sqlite', 64 AUTH_DATABASE_PATH: './data/system.sqlite', 65 AUTH_REALMS_PATH: './data/realms', 66 }, 67 () => { 68 const cfg = loadConfig(); 69 assert.equal(cfg.database.dialect, 'sqlite'); 70 assert.equal(cfg.database.path, './data/system.sqlite'); 71 assert.equal(cfg.database.realms, './data/realms'); 72 assert.throws(() => { 73 cfg.server.port = 1; 74 }, TypeError); 75 } 76 ) 77 ); 78 }); 79 80 test('an unsupported dialect is rejected', async () => { 81 await inTempDir(() => 82 withEnv( 83 { 84 AUTH_DATABASE_DIALECT: 'mysql', 85 AUTH_DATABASE_PATH: './data/system.sqlite', 86 AUTH_REALMS_PATH: './data/realms', 87 }, 88 () => { 89 assert.throws(() => loadConfig(), /database\.dialect/); 90 } 91 ) 92 ); 93 }); 94 95 test('a non-integer port names the environment variable', async () => { 96 await inTempDir(() => 97 withEnv( 98 { 99 AUTH_DATABASE_PATH: './data/system.sqlite', 100 AUTH_REALMS_PATH: './data/realms', 101 AUTH_PORT: 'http', 102 }, 103 () => { 104 assert.throws(() => loadConfig(), /AUTH_PORT/); 105 } 106 ) 107 ); 108 }); 109 110 test('environment variables override the YAML file', async () => { 111 await inTempDir(async () => { 112 await fs.writeFile( 113 'auth.yaml', 114 [ 115 'server:', 116 ' port: 9999', 117 'database:', 118 ' dialect: sqlite', 119 ' path: ./file/system.sqlite', 120 ' realms: ./file/realms', 121 '', 122 ].join('\n') 123 ); 124 125 await withEnv({ AUTH_PORT: '7777', AUTH_DATABASE_PATH: './env/system.sqlite' }, () => { 126 const cfg = loadConfig(); 127 assert.equal(cfg.server.port, 7777); 128 assert.equal(cfg.database.path, './env/system.sqlite'); 129 assert.equal(cfg.database.realms, './file/realms'); 130 }); 131 }); 132 });