test(calculate-version): 整併單元測試至 app/test 並移除無法執行的重複測試目錄 #7

Closed
jiantw83 wants to merge 6 commits from test/consolidate-app-test-20260626-111823 into develop
2 changed files with 17 additions and 3 deletions
Showing only changes of commit b8804c5218 - Show all commits
+14 -2
View File
@@ -55,20 +55,32 @@ function assertHttpUrl(name, value) {
}
}
// 驗證 repository 為 owner/repo 格式(僅允許字母數字與 . _ -,且拒絕 . 與 .. 路徑穿越段)
function assertRepository(name, value) {
const parts = value.split('/');
const valid = parts.length === 2
Review

嚴重等級🟡 警告
審查員:Maya
問題:新增的 assertRepository 函式缺乏對 owner/repo 字串長度的邊界檢查,且變數名稱 valid 過於通用,語義不夠明確。
建議:建議在 assertRepository 中加入長度限制檢查,並將 valid 更名為 isRepoFormatValid 或類似具備明確語義的命名。

**嚴重等級**:🟡 警告 **審查員**:Maya **問題**:新增的 `assertRepository` 函式缺乏對 owner/repo 字串長度的邊界檢查,且變數名稱 `valid` 過於通用,語義不夠明確。 **建議**:建議在 `assertRepository` 中加入長度限制檢查,並將 `valid` 更名為 `isRepoFormatValid` 或類似具備明確語義的命名。
&& parts.every((part) => /^[A-Za-z0-9._-]+$/.test(part) && part !== '.' && part !== '..');
if (!valid) {
throw new Error(`${name} 格式錯誤,必須為 owner/repo`);
}
}
/**
* 從環境變數載入並驗證執行所需的設定。
*
* GITEA_SERVER_URL 與 GITEA_REPOSITORY 為必填,未設定時會拋出錯誤;GITEA_SERVER_URL
* 另需為合法的 http/https URLGITEA_TOKEN 為非必填,未設定時為 null;IS_BETA 會被正規化為布林值。
* 另需為合法的 http/https URLGITEA_REPOSITORY 另需為 owner/repo 格式;
* GITEA_TOKEN 為非必填,未設定時為 null;IS_BETA 會被正規化為布林值。
*
* @param {Object} [env=process.env] - 環境變數來源物件,預設為 process.env。
* @returns {{ serverUrl: string, repository: string, token: (string|null), isBeta: boolean }} 已驗證的設定物件。
* @throws {Error} 當 GITEA_SERVER_URL 或 GITEA_REPOSITORY 未設定,或 GITEA_SERVER_URL 非合法 http/https URL 時拋出。
* @throws {Error} 當必填項未設定、GITEA_SERVER_URL 非合法 http/https URL,或 GITEA_REPOSITORY 非 owner/repo 格式時拋出。
*/
function loadConfig(env = process.env) {
const serverUrl = requireEnv('GITEA_SERVER_URL', env.GITEA_SERVER_URL);
assertHttpUrl('GITEA_SERVER_URL', serverUrl);
const repository = requireEnv('GITEA_REPOSITORY', env.GITEA_REPOSITORY);
assertRepository('GITEA_REPOSITORY', repository);
const token = isUnset(env.GITEA_TOKEN) ? null : env.GITEA_TOKEN;
const isBeta = normalizeBetaFlag(env.IS_BETA);
+3 -1
View File
@@ -63,7 +63,9 @@ async function fetchReleases(baseUrl, options = {}) {
try {
pageJson = JSON.parse(text);
} catch {
throw new Error(`release API 回傳資料無法解析 (page=${page})`);
// 附上截斷的回傳內容片段,便於除錯回傳格式異常
const snippet = text.slice(0, 200);
Review

嚴重等級🔵 建議
審查員:Bard
問題:將截斷字串直接串接在 Error 訊息中若處理不當易造成混淆,變數名稱 snippet 語義不明確。
建議:建議在錯誤訊息中對片段內容進行適當標記,並將變數更名為 contentSnippet

**嚴重等級**:🔵 建議 **審查員**:Bard **問題**:將截斷字串直接串接在 Error 訊息中若處理不當易造成混淆,變數名稱 `snippet` 語義不明確。 **建議**:建議在錯誤訊息中對片段內容進行適當標記,並將變數更名為 `contentSnippet`。
throw new Error(`release API 回傳資料無法解析 (page=${page}): ${snippet}`);
Review

嚴重等級🔴 嚴重
審查員:Maya
問題:新增的異常處理邏輯截斷了 text 為 200 字元,但在 text 為極大值或無法轉為字串時未進行防禦性檢查,且截斷點可能將多位元組字元拆分導致亂碼。
建議:請確保 text 是字串後再截斷,並使用正確處理多位元組字元的方式(如 Array.from(text).slice(0, 200).join(''))以避免亂碼。

**嚴重等級**:🔴 嚴重 **審查員**:Maya **問題**:新增的異常處理邏輯截斷了 `text` 為 200 字元,但在 `text` 為極大值或無法轉為字串時未進行防禦性檢查,且截斷點可能將多位元組字元拆分導致亂碼。 **建議**:請確保 `text` 是字串後再截斷,並使用正確處理多位元組字元的方式(如 `Array.from(text).slice(0, 200).join('')`)以避免亂碼。
}
if (pageJson === null) {