test(release-cleanup): 補齊 cleanup/config/main 與新驗證函式測試
新增 cleanupReleases、cleanupOrphanTags 的失敗路徑與分類測試、 loadConfig 環境變數驗證測試、main 整合測試,以及 requireUrl/ requireRepository 與 content-type 檢查測試。測試共 41 項全數通過。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
154ab032bf
commit
7c225d4122
@@ -1,6 +1,6 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { selectReleasesToDelete } from '../releases.js'
|
||||
import { selectReleasesToDelete, cleanupReleases } from '../releases.js'
|
||||
|
||||
const releases = [
|
||||
{ id: 1, tag_name: 'v1.0.0', created_at: '2024-01-01T00:00:00Z' },
|
||||
@@ -32,3 +32,74 @@ test('selectReleasesToDelete 不改動原陣列', () => {
|
||||
selectReleasesToDelete(releases, 1)
|
||||
assert.deepEqual(releases, original)
|
||||
})
|
||||
|
||||
test('selectReleasesToDelete 對無效 created_at 視為最舊,不產生 NaN 排序', () => {
|
||||
const list = [
|
||||
{ id: 1, tag_name: 'good', created_at: '2024-05-01T00:00:00Z' },
|
||||
{ id: 2, tag_name: 'bad', created_at: 'not-a-date' },
|
||||
{ id: 3, tag_name: 'empty' },
|
||||
]
|
||||
const toDelete = selectReleasesToDelete(list, 1)
|
||||
// 最新的 good 被保留;兩筆無效日期視為最舊,落入待刪除
|
||||
assert.equal(toDelete.length, 2)
|
||||
assert.ok(!toDelete.some((r) => r.tag_name === 'good'))
|
||||
})
|
||||
|
||||
// 建立可記錄刪除呼叫的假 client
|
||||
function fakeClient(releases, statusFor = () => 204) {
|
||||
const deleted = []
|
||||
return {
|
||||
deleted,
|
||||
async fetchAllPages() {
|
||||
return releases
|
||||
},
|
||||
async deleteResource(url) {
|
||||
deleted.push(url)
|
||||
return statusFor(url)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
test('cleanupReleases 刪除超出保留數的舊 release', async () => {
|
||||
const client = fakeClient([
|
||||
{ id: 1, tag_name: 'v1', name: 'n1', created_at: '2024-01-01T00:00:00Z' },
|
||||
{ id: 2, tag_name: 'v2', name: 'n2', created_at: '2024-02-01T00:00:00Z' },
|
||||
{ id: 3, tag_name: 'v3', name: 'n3', created_at: '2024-03-01T00:00:00Z' },
|
||||
])
|
||||
await cleanupReleases(client, { releaseApiUrl: 'http://x/releases', keepCount: 1 })
|
||||
// 保留最新 v3,刪除 v2 與 v1
|
||||
assert.deepEqual(client.deleted, ['http://x/releases/2', 'http://x/releases/1'])
|
||||
})
|
||||
|
||||
test('cleanupReleases 在未超過保留數時不刪除', async () => {
|
||||
const client = fakeClient([
|
||||
{ id: 1, tag_name: 'v1', name: 'n1', created_at: '2024-01-01T00:00:00Z' },
|
||||
])
|
||||
await cleanupReleases(client, { releaseApiUrl: 'http://x/releases', keepCount: 2 })
|
||||
assert.equal(client.deleted.length, 0)
|
||||
})
|
||||
|
||||
test('cleanupReleases 在 deleteResource 回傳非 204 時仍繼續處理其餘項目', async () => {
|
||||
const client = fakeClient(
|
||||
[
|
||||
{ id: 1, tag_name: 'v1', name: 'n1', created_at: '2024-01-01T00:00:00Z' },
|
||||
{ id: 2, tag_name: 'v2', name: 'n2', created_at: '2024-02-01T00:00:00Z' },
|
||||
{ id: 3, tag_name: 'v3', name: 'n3', created_at: '2024-03-01T00:00:00Z' },
|
||||
],
|
||||
(url) => (url.endsWith('/2') ? 500 : 204), // v2 刪除失敗
|
||||
)
|
||||
await cleanupReleases(client, { releaseApiUrl: 'http://x/releases', keepCount: 1 })
|
||||
// 即使 v2 失敗(500),v1 仍被嘗試刪除
|
||||
assert.deepEqual(client.deleted, ['http://x/releases/2', 'http://x/releases/1'])
|
||||
})
|
||||
|
||||
test('cleanupReleases 略過沒有 id 的 release', async () => {
|
||||
const client = fakeClient([
|
||||
{ id: 1, tag_name: 'v3', name: 'n3', created_at: '2024-03-01T00:00:00Z' },
|
||||
{ id: null, tag_name: 'v1', name: 'n1', created_at: '2024-01-01T00:00:00Z' },
|
||||
{ id: 2, tag_name: 'v2', name: 'n2', created_at: '2024-02-01T00:00:00Z' },
|
||||
])
|
||||
await cleanupReleases(client, { releaseApiUrl: 'http://x/releases', keepCount: 1 })
|
||||
// 保留最新 v3;待刪除為 v2 與 (無 id 的) v1 → 無 id 者被略過
|
||||
assert.deepEqual(client.deleted, ['http://x/releases/2'])
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user