test(ai-review): 補使用量統計與 resolve 安全與邊界測試

This commit is contained in:
Jeffery
2026-06-23 12:58:43 +08:00
parent f23d015e62
commit a27555b35a
3 changed files with 247 additions and 0 deletions
+27
View File
@@ -177,6 +177,33 @@ describe('reconcileConversations', () => {
assert.deepEqual(result.carriedFindings.map(f => f.suggestion).sort(), ['fix one', 'fix two']);
});
it('treats a file as empty and continues when getFileContent throws', async () => {
const deps = baseDeps();
deps.getFileContent = async (path) => { if (path === 'a.js') throw new Error('404'); return 'some code'; };
// judge 收到的 a.js code 應為空字串,仍照常判斷、不丟例外
let seenCode;
deps.judge = async (items) => { seenCode = items.find(it => it.path === 'a.js')?.code; return items.map(it => ({ idx: it.idx, resolved: false })); };
const result = await reconcileConversations(deps);
assert.equal(seenCode, '');
assert.equal(result.resolvedCount, 0);
assert.equal(result.carriedFindings.length, 2); // a.js + b.js 加回(c.js 已解決略過)
});
it('skips path-traversal file paths without calling getFileContent', async () => {
const requested = [];
const deps = baseDeps();
deps.listComments = async () => [
{ id: 1, path: '../../etc/passwd', position: 1, body: reviewBody('🔴 嚴重', 'Assassin', 'p', 's') },
{ id: 2, path: 'b.js', position: 20, body: reviewBody('🟡 警告', 'Mage', 'p2', 'fix two') },
];
deps.getFileContent = async (path) => { requested.push(path); return 'code'; };
deps.judge = async (items) => items.map(it => ({ idx: it.idx, resolved: false }));
await reconcileConversations(deps);
assert.deepEqual(requested, ['b.js']); // 不安全路徑未被請求
});
it('returns empty result and does not throw when listing comments fails', async () => {
const result = await reconcileConversations({ listComments: async () => { throw new Error('boom'); } });
assert.deepEqual(result, { resolvedFindings: [], carriedFindings: [], resolvedCount: 0, unresolvedCount: 0 });