import { test } from 'node:test' import assert from 'node:assert/strict' import { isEmptyOrNull, requireValue, requireInteger, requireUrl, requireRepository, } from '../validate.js' test('isEmptyOrNull 對空值回傳 true', () => { assert.equal(isEmptyOrNull(''), true) assert.equal(isEmptyOrNull(null), true) assert.equal(isEmptyOrNull(undefined), true) assert.equal(isEmptyOrNull('null'), true) }) test('isEmptyOrNull 對有效值回傳 false', () => { assert.equal(isEmptyOrNull('value'), false) assert.equal(isEmptyOrNull('0'), false) assert.equal(isEmptyOrNull(0), false) }) test('requireValue 對空值丟出錯誤', () => { assert.throws(() => requireValue('NAME', ''), /NAME is required/) assert.throws(() => requireValue('NAME', 'null'), /NAME is required/) }) test('requireValue 對有效值不丟出錯誤', () => { assert.doesNotThrow(() => requireValue('NAME', 'value')) }) test('requireInteger 接受非負整數', () => { assert.doesNotThrow(() => requireInteger('KEEP_COUNT', '0')) assert.doesNotThrow(() => requireInteger('KEEP_COUNT', '10')) assert.doesNotThrow(() => requireInteger('KEEP_COUNT', 5)) }) test('requireInteger 拒絕非整數或負數', () => { assert.throws(() => requireInteger('KEEP_COUNT', '-1'), /non-negative integer/) assert.throws(() => requireInteger('KEEP_COUNT', '1.5'), /non-negative integer/) assert.throws(() => requireInteger('KEEP_COUNT', 'abc'), /non-negative integer/) }) test('requireUrl 接受 http/https URL', () => { assert.doesNotThrow(() => requireUrl('URL', 'https://gitea.example.com')) assert.doesNotThrow(() => requireUrl('URL', 'http://localhost:3000')) }) test('requireUrl 拒絕非法 URL 或非 http(s) 協定', () => { assert.throws(() => requireUrl('URL', 'not a url'), /must be a valid URL/) assert.throws(() => requireUrl('URL', 'ftp://example.com'), /http or https/) assert.throws(() => requireUrl('URL', 'file:///etc/passwd'), /http or https/) }) test('requireRepository 接受合法 owner/repo', () => { assert.doesNotThrow(() => requireRepository('REPO', 'owner/repo')) assert.doesNotThrow(() => requireRepository('REPO', 'my-org/my_repo.git')) }) test('requireRepository 拒絕路徑穿越或格式錯誤', () => { assert.throws(() => requireRepository('REPO', '../evil'), /owner\/repo/) assert.throws(() => requireRepository('REPO', 'owner/repo/extra'), /owner\/repo/) assert.throws(() => requireRepository('REPO', 'noslash'), /owner\/repo/) assert.throws(() => requireRepository('REPO', 'owner/..'), /owner\/repo/) })