'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { isUnset, requireEnv, normalizeBetaFlag, loadConfig, } = require('../config'); test('isUnset 對 undefined/null/空字串/字面 "null" 視為未設定', () => { assert.equal(isUnset(undefined), true); assert.equal(isUnset(null), true); assert.equal(isUnset(''), true); assert.equal(isUnset('null'), true); }); test('isUnset 對其他非空值視為已設定', () => { assert.equal(isUnset('value'), false); assert.equal(isUnset('false'), false); assert.equal(isUnset('0'), false); }); test('requireEnv 未設定時拋錯', () => { assert.throws(() => requireEnv('FOO', ''), /FOO 未設定/); assert.throws(() => requireEnv('FOO', undefined), /FOO 未設定/); }); test('requireEnv 有值時回傳原值', () => { assert.equal(requireEnv('FOO', 'bar'), 'bar'); }); test('normalizeBetaFlag 僅 "true" 視為啟用', () => { assert.equal(normalizeBetaFlag('true'), true); assert.equal(normalizeBetaFlag('false'), false); assert.equal(normalizeBetaFlag(undefined), false); assert.equal(normalizeBetaFlag('TRUE'), false); }); test('loadConfig 解析完整設定', () => { const config = loadConfig({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: 'owner/repo', GITEA_TOKEN: 'secret', IS_BETA: 'true', }); assert.deepEqual(config, { serverUrl: 'https://gitea.example.com', repository: 'owner/repo', token: 'secret', isBeta: true, }); }); test('loadConfig 缺少 token 視為匿名(null)', () => { const config = loadConfig({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: 'owner/repo', GITEA_TOKEN: 'null', }); assert.equal(config.token, null); assert.equal(config.isBeta, false); }); test('loadConfig 缺少必填項目時拋錯', () => { assert.throws(() => loadConfig({ GITEA_REPOSITORY: 'owner/repo' }), /GITEA_SERVER_URL 未設定/); }); test('loadConfig 於 GITEA_SERVER_URL 非合法 URL 時拋錯', () => { assert.throws(() => loadConfig({ GITEA_SERVER_URL: 'not-a-url', GITEA_REPOSITORY: 'owner/repo', }), /GITEA_SERVER_URL 格式錯誤/); }); test('loadConfig 於 GITEA_SERVER_URL 使用非 http(s) 協定時拋錯', () => { assert.throws(() => loadConfig({ GITEA_SERVER_URL: 'ftp://gitea.example.com', GITEA_REPOSITORY: 'owner/repo', }), /必須使用 http 或 https/); }); test('loadConfig 於 GITEA_REPOSITORY 格式錯誤或含路徑穿越時拋錯', () => { assert.throws(() => loadConfig({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: '../evil', }), /GITEA_REPOSITORY 格式錯誤/); assert.throws(() => loadConfig({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: 'owner/repo/extra', }), /GITEA_REPOSITORY 格式錯誤/); }); test('loadConfig 於 GITEA_REPOSITORY 邊界格式(空段/缺斜線/多段)皆拋錯', () => { for (const repo of ['noslash', 'owner/', '/repo', 'a/b/c', 'owner//repo']) { assert.throws(() => loadConfig({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: repo, }), /GITEA_REPOSITORY 格式錯誤/, `應拒絕:${repo}`); } }); test('loadConfig 於 GITEA_REPOSITORY 含非法字元或超長段時拋錯', () => { const bad = [ 'ow ner/repo', 'owner/re*po', 'owner/re:po', `${'a'.repeat(101)}/repo`, ]; for (const repo of bad) { assert.throws(() => loadConfig({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: repo, }), /GITEA_REPOSITORY 格式錯誤/, `應拒絕:${repo}`); } }); test('loadConfig 接受含點號的合法 owner/repo', () => { const config = loadConfig({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: 'my.org/my.repo', }); assert.equal(config.repository, 'my.org/my.repo'); });