diff --git a/app/comments.test.js b/app/comments.test.js index 78b0e0f..0f8dc33 100644 --- a/app/comments.test.js +++ b/app/comments.test.js @@ -137,6 +137,17 @@ describe('postNewCriticalComments', () => { assert.match(issueCalls[0], /嚴重問題/); }); + it('posts critical findings to the issue updater when inline comments are disabled', async () => { + const issueCalls = []; + await postNewCriticalComments([critical], { + postInline: null, + postIssue: async (body) => { issueCalls.push(body); }, + }); + assert.equal(issueCalls.length, 1); + assert.match(issueCalls[0], /嚴重問題/); + assert.match(issueCalls[0], /app\/preflight\.js:19/); + }); + it('only posts for new critical findings', async () => { const inlineCalls = []; const issueCalls = []; diff --git a/app/config.test.js b/app/config.test.js index dec24c9..4286e1a 100644 --- a/app/config.test.js +++ b/app/config.test.js @@ -114,6 +114,13 @@ describe('getLLMConfig', () => { assert.equal(shouldSkipOpenCodeTLSVerify(), false); }); + it('skips OpenCode TLS verification for non-false values', () => { + for (const value of ['', '0', 'true', 'yes']) { + process.env.OPENCODE_SKIP_TLS_VERIFY = value; + assert.equal(shouldSkipOpenCodeTLSVerify(), true); + } + }); + it('openai takes priority over gemini when both set', () => { process.env.OPENAI_API_KEY = 'sk-test'; process.env.GEMINI_API_KEY = 'gemini-key'; diff --git a/app/gitea.test.js b/app/gitea.test.js index 89c5a3a..a7a7865 100644 --- a/app/gitea.test.js +++ b/app/gitea.test.js @@ -1,7 +1,7 @@ import { describe, it, afterEach, mock } from 'node:test'; import assert from 'node:assert/strict'; import axios from 'axios'; -import { getPRDiff, filterDiff, postComment, postPullReviewComment, getCommitMessageBySha, getBranchHeadCommitMessage, shouldSkipBotCommit, getBotReviewOutcome } from './gitea.js'; +import { getPRDiff, filterDiff, postComment, updateComment, postPullReviewComment, getCommitMessageBySha, getBranchHeadCommitMessage, shouldSkipBotCommit, getBotReviewOutcome } from './gitea.js'; afterEach(() => mock.restoreAll()); @@ -57,6 +57,22 @@ describe('gitea', () => { await assert.rejects(() => postComment('test'), /api error/); }); + it('updateComment patches an existing issue comment with body', async () => { + let capturedUrl, capturedBody, capturedOpts; + mock.method(axios, 'patch', async (url, body, opts) => { + capturedUrl = url; + capturedBody = body; + capturedOpts = opts; + return { data: { id: 123, body: body.body } }; + }); + const result = await updateComment(123, 'updated body'); + assert.deepEqual(result, { id: 123, body: 'updated body' }); + assert.ok(capturedUrl.includes('/api/v1/repos/')); + assert.ok(capturedUrl.endsWith('/issues/comments/123')); + assert.equal(capturedBody.body, 'updated body'); + assert.ok(capturedOpts.headers['Authorization'].startsWith('token ')); + }); + it('postPullReviewComment posts an inline review comment to the pulls reviews API', async () => { let capturedUrl, capturedBody, capturedOpts; mock.method(axios, 'post', async (url, body, opts) => { diff --git a/app/preflight.test.js b/app/preflight.test.js index 0270c33..6cc0d33 100644 --- a/app/preflight.test.js +++ b/app/preflight.test.js @@ -199,6 +199,23 @@ describe('verifyLLM', () => { assert.equal(agents[1].options.rejectUnauthorized, false); }); + it('passes an insecure https agent for opencode when TLS skip is explicitly true', async () => { + clearLLMEnv(); + process.env.OPENCODE_BASE_URL = 'https://opencode.local:4096'; + process.env.OPENCODE_SKIP_TLS_VERIFY = 'true'; + const agents = []; + mock.method(axios, 'get', async (url, opts) => { + agents.push(opts.httpsAgent); + if (url.endsWith('/global/health')) return { data: { healthy: true } }; + return { data: { providers: [{ id: 'google', models: { 'gemini-2.5-flash': { id: 'gemini-2.5-flash' } } }] } }; + }); + const result = await verifyLLM(); + assert.equal(result.ok, true); + assert.equal(agents.length, 2); + assert.equal(agents[0].options.rejectUnauthorized, false); + assert.equal(agents[1].options.rejectUnauthorized, false); + }); + it('does not pass an insecure https agent for opencode when TLS verification is enabled', async () => { clearLLMEnv(); process.env.OPENCODE_BASE_URL = 'https://opencode.local:4096';