新增 cleanupReleases、cleanupOrphanTags 的失敗路徑與分類測試、 loadConfig 環境變數驗證測試、main 整合測試,以及 requireUrl/ requireRepository 與 content-type 檢查測試。測試共 41 項全數通過。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
101 lines
2.7 KiB
JavaScript
101 lines
2.7 KiB
JavaScript
import { test, afterEach } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { GiteaClient } from '../gitea-client.js'
|
|
|
|
const realFetch = globalThis.fetch
|
|
|
|
afterEach(() => {
|
|
globalThis.fetch = realFetch
|
|
})
|
|
|
|
// 建立模擬的 JSON 回應(含 content-type 標頭)
|
|
function jsonResponse(data) {
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
headers: { get: () => 'application/json' },
|
|
json: async () => data,
|
|
text: async () => JSON.stringify(data),
|
|
}
|
|
}
|
|
|
|
test('建構子在有 token 時帶上 Authorization 標頭', () => {
|
|
const client = new GiteaClient({ token: 'abc' })
|
|
assert.equal(client.headers.Authorization, 'token abc')
|
|
})
|
|
|
|
test('建構子在無 token 時不帶 Authorization 標頭', () => {
|
|
const client = new GiteaClient({})
|
|
assert.equal(client.headers.Authorization, undefined)
|
|
})
|
|
|
|
test('fetchAllPages 逐頁讀取直到空陣列', async () => {
|
|
const pages = {
|
|
1: [{ id: 1 }, { id: 2 }],
|
|
2: [{ id: 3 }],
|
|
3: [],
|
|
}
|
|
const requested = []
|
|
globalThis.fetch = async (url) => {
|
|
const page = new URL(url).searchParams.get('page')
|
|
requested.push(page)
|
|
return jsonResponse(pages[page])
|
|
}
|
|
|
|
const client = new GiteaClient({})
|
|
const items = await client.fetchAllPages('https://example.com/api')
|
|
|
|
assert.deepEqual(
|
|
items.map((i) => i.id),
|
|
[1, 2, 3],
|
|
)
|
|
assert.deepEqual(requested, ['1', '2', '3'])
|
|
})
|
|
|
|
test('fetchAllPages 帶上逾時 signal', async () => {
|
|
let sawSignal = false
|
|
globalThis.fetch = async (_url, opts) => {
|
|
sawSignal = opts && typeof opts.signal === 'object' && opts.signal !== null
|
|
return jsonResponse([])
|
|
}
|
|
const client = new GiteaClient({})
|
|
await client.fetchAllPages('https://example.com/api')
|
|
assert.equal(sawSignal, true)
|
|
})
|
|
|
|
test('fetchAllPages 在 HTTP 錯誤時丟出例外', async () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: false,
|
|
status: 500,
|
|
text: async () => 'boom',
|
|
})
|
|
const client = new GiteaClient({})
|
|
await assert.rejects(
|
|
() => client.fetchAllPages('https://example.com/api'),
|
|
/HTTP 500/,
|
|
)
|
|
})
|
|
|
|
test('fetchAllPages 在回應非 JSON 時丟出例外', async () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
headers: { get: () => 'text/html' },
|
|
text: async () => '<html>error</html>',
|
|
})
|
|
const client = new GiteaClient({})
|
|
await assert.rejects(
|
|
() => client.fetchAllPages('https://example.com/api'),
|
|
/non-JSON content-type/,
|
|
)
|
|
})
|
|
|
|
test('deleteResource 回傳 HTTP 狀態碼', async () => {
|
|
globalThis.fetch = async (url, opts) => {
|
|
assert.equal(opts.method, 'DELETE')
|
|
return { status: 204 }
|
|
}
|
|
const client = new GiteaClient({})
|
|
assert.equal(await client.deleteResource('https://example.com/api/1'), 204)
|
|
})
|