85 lines
3.4 KiB
JavaScript
85 lines
3.4 KiB
JavaScript
'use strict';
|
||
|
||
/** Gitea 会话展示契约回归:不启动 server,只校验数据协议和脱敏链路。 */
|
||
const assert = require('node:assert/strict');
|
||
const fs = require('node:fs');
|
||
const path = require('node:path');
|
||
const { normalizeWebhookEvent } = require('../lib/gitea-webhook');
|
||
const { buildWorkflowPrompt } = require('../lib/gitea-workflow-codex');
|
||
|
||
const serverSource = fs.readFileSync(path.join(__dirname, '..', 'server.js'), 'utf8');
|
||
const appSource = fs.readFileSync(path.join(__dirname, '..', 'public', 'app.js'), 'utf8');
|
||
const styleSource = fs.readFileSync(path.join(__dirname, '..', 'public', 'style.css'), 'utf8');
|
||
|
||
function fixturePayload() {
|
||
return {
|
||
repository: {
|
||
owner: { login: 'shiyue' },
|
||
name: 'kan',
|
||
full_name: 'shiyue/kan',
|
||
clone_url: 'https://gitea.example/shiyue/kan.git',
|
||
},
|
||
issue: { number: 1, title: '这里是测试bot' },
|
||
comment: {
|
||
id: 9,
|
||
body: '@codexbot 再测试一次',
|
||
user: { login: 'alice' },
|
||
},
|
||
sender: { login: 'alice' },
|
||
};
|
||
}
|
||
|
||
function run() {
|
||
const event = normalizeWebhookEvent({
|
||
payload: fixturePayload(),
|
||
headers: { 'x-gitea-event': 'issue_comment' },
|
||
botIdentity: { login: 'codexbot' },
|
||
});
|
||
assert.equal(event.ignored, false);
|
||
assert.equal(event.resource.title, '这里是测试bot');
|
||
assert.equal(event.mention.instruction, '再测试一次');
|
||
|
||
const prompt = buildWorkflowPrompt({
|
||
taskId: 'task-ui',
|
||
turnId: 'turn-ui',
|
||
resourceKey: 'default:shiyue/kan:issue:1',
|
||
workspacePath: '/home/hdzx/giteabot/shiyue/kan',
|
||
instruction: event.mention.instruction,
|
||
});
|
||
assert.match(prompt, /工作区:\/home\/hdzx\/giteabot\/shiyue\/kan/);
|
||
assert.match(prompt, /用户指令:\n再测试一次/);
|
||
assert.match(prompt, /final 隐藏标记/);
|
||
|
||
// Codex 仍接收 runtimeText;历史用户消息使用 displayText,避免内部 Prompt 进入用户气泡。
|
||
assert.match(serverSource, /const displayText = giteaDisplayMessage\(task, event\)/);
|
||
assert.match(serverSource, /text: displayText, mode: 'yolo', agent: 'codexapp'/);
|
||
assert.match(serverSource, /runtimeText: prompt/);
|
||
assert.match(serverSource, /content: displayTextValue/);
|
||
assert.match(serverSource, /const giteaSource = normalizeGiteaSource\(options\.giteaSource\)/);
|
||
assert.match(serverSource, /persistedUserMessage\.giteaSource = giteaSource/);
|
||
|
||
// 标题优先 Issue/PR resource.title,旧资源键仅作兜底。
|
||
assert.match(serverSource, /title: issueTitle \|\| legacyTitle/);
|
||
assert.match(serverSource, /session\.title === legacyTitle/);
|
||
assert.match(serverSource, /let sessionCreated = false/);
|
||
assert.match(serverSource, /if \(sessionCreated && !presentationChanged\) broadcastSessionList\(\)/);
|
||
|
||
// 前端既显示来源标记,也会把旧完整 Prompt 脱敏为简短来源消息。
|
||
assert.match(appSource, /来自 gitea 消息:/);
|
||
assert.match(appSource, /gitea-message-label/);
|
||
assert.match(appSource, /session-item-source-badge/);
|
||
assert.match(appSource, /function getGiteaVisibleMessageContent/);
|
||
assert.match(appSource, /已收到工单请求,请读取工单上下文/);
|
||
assert.match(styleSource, /\.msg\.gitea-message \.msg-bubble/);
|
||
assert.match(styleSource, /\.session-item-source-badge/);
|
||
|
||
console.log('Gitea Workflow UI unit checks passed');
|
||
}
|
||
|
||
try {
|
||
run();
|
||
} catch (error) {
|
||
console.error(error.stack || error.message || error);
|
||
process.exitCode = 1;
|
||
}
|