import { test, afterEach } from 'node:test' import assert from 'node:assert/strict' import { spawnSync } from 'node:child_process' import { fileURLToPath } from 'node:url' import { main } from '../index.js' const realFetch = globalThis.fetch const savedEnv = { ...process.env } afterEach(() => { globalThis.fetch = realFetch process.env = { ...savedEnv } }) function setEnv(env) { for (const key of ['GITEA_SERVER_URL', 'GITEA_REPOSITORY', 'KEEP_COUNT', 'GITEA_TOKEN']) { delete process.env[key] } Object.assign(process.env, env) } test('main 在環境變數有效且 API 正常時順利完成', async () => { setEnv({ GITEA_SERVER_URL: 'https://gitea.example.com', GITEA_REPOSITORY: 'owner/repo', KEEP_COUNT: '2', }) // 所有清單端點皆回空陣列(無 release、無 tag) globalThis.fetch = async () => ({ ok: true, status: 200, headers: { get: () => 'application/json' }, json: async () => [], }) await main() // 不應拋出 }) test('main 在必填環境變數缺失時 reject(供整合層級驗證錯誤處理)', async () => { setEnv({ GITEA_REPOSITORY: 'owner/repo', KEEP_COUNT: '2', }) await assert.rejects(() => main(), /GITEA_SERVER_URL is required/) }) test('直接執行 index.js 在設定錯誤時以非零狀態碼結束', () => { const indexPath = fileURLToPath(new URL('../index.js', import.meta.url)) // 僅帶 PATH,不提供任何必填環境變數,使 main 拋錯並觸發 process.exit(1) const result = spawnSync(process.execPath, [indexPath], { env: { PATH: process.env.PATH }, encoding: 'utf8', }) assert.equal(result.status, 1) assert.match(result.stderr, /GITEA_SERVER_URL is required/) })