From 55bd14e480ad42d2ecc4ca49ad5ae782a6f80321 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Tue, 23 Jun 2026 13:15:58 +0800 Subject: [PATCH] =?UTF-8?q?test(ai-review):=20=E6=9B=B4=E6=96=B0=E7=B5=B1?= =?UTF-8?q?=E8=A8=88=E5=9B=9B=E6=AC=84=E3=80=81OpenRouter=20=E7=B2=BE?= =?UTF-8?q?=E7=A2=BA=E6=AF=94=E5=B0=8D=E8=88=87=20codeWindow=20=E9=82=8A?= =?UTF-8?q?=E7=95=8C=E6=B8=AC=E8=A9=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/comments.test.js | 12 ++++++------ app/resolve.test.js | 7 +++++++ app/usage.test.js | 10 +++++----- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/comments.test.js b/app/comments.test.js index 66972ba..2db21fe 100644 --- a/app/comments.test.js +++ b/app/comments.test.js @@ -104,21 +104,21 @@ describe('formatFindingsStats', () => { { level: 'custom', is_new: true }, ]; - it('formats old and new findings by severity', () => { + it('formats old and new findings by severity with an unclassified column', () => { const stats = formatFindingsStats(statsFindings); assert.equal(stats, [ - '| 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 |', - '| --- | --- | --- | --- |', - '| 舊問題 | 1 筆 | 0 筆 | 0 筆 |', - '| 新問題 | 0 筆 | 1 筆 | 1 筆 |', + '| 類型 | 🔴 嚴重 | 🟡 警告 | 🔵 建議 | ⚪ 無法標示 |', + '| --- | --- | --- | --- | --- |', + '| 新問題 | 0 筆 | 1 筆 | 1 筆 | 1 筆 |', + '| 舊問題 | 1 筆 | 0 筆 | 0 筆 | 0 筆 |', ].join('\n')); }); it('formats compact one-line stats for action logs', () => { assert.equal( formatFindingsStatsLine(statsFindings), - '舊: 嚴重1 / 警告0 / 建議0;新: 嚴重0 / 警告1 / 建議1', + '新: 嚴重0 / 警告1 / 建議1 / 無法標示1;舊: 嚴重1 / 警告0 / 建議0 / 無法標示0', ); }); }); diff --git a/app/resolve.test.js b/app/resolve.test.js index 9e18840..1c00f10 100644 --- a/app/resolve.test.js +++ b/app/resolve.test.js @@ -86,6 +86,13 @@ describe('codeWindow', () => { it('returns empty string for empty content', () => { assert.equal(codeWindow('', 10), ''); }); + + it('handles out-of-range line numbers without throwing', () => { + const content = Array.from({ length: 10 }, (_, i) => `line${i + 1}`).join('\n'); + assert.doesNotThrow(() => codeWindow(content, -5, 2)); + assert.equal(codeWindow(content, 0, 1), '1: line1\n2: line2'); // 非正數行號 → 從開頭取窗 + assert.equal(codeWindow(content, 9999, 2), ''); // 超過檔尾 → 空字串,不丟錯 + }); }); describe('judgeConversationsResolved', () => { diff --git a/app/usage.test.js b/app/usage.test.js index fb5adf6..7a1fd5d 100644 --- a/app/usage.test.js +++ b/app/usage.test.js @@ -100,11 +100,11 @@ describe('fetchAccountQuota', () => { } }); - it('accepts a real openrouter subdomain', async () => { - const get = async () => ({ data: { data: { usage: 1, limit: 10, limit_remaining: 9 } } }); - const q = await fetchAccountQuota('openai', { apiKeys: ['k'], baseURL: 'https://api.openrouter.ai/api/v1' }, { get }); - assert.equal(q.available, true); - assert.equal(q.source, 'openrouter'); + it('only accepts the exact openrouter.ai apex host (subdomains are not OpenRouter)', async () => { + const get = async () => { throw new Error('should not be called for non-apex host'); }; + const q = await fetchAccountQuota('openai', { apiKeys: ['sk-secret'], baseURL: 'https://api.openrouter.ai/api/v1' }, { get }); + assert.equal(q.available, false); + assert.match(q.reason, /API key 無法取得/); }); it('reports 不適用 for local platforms', async () => {