Files
2026Technology-Competition/tests/test_chat_state.js
T
lhl be79624db5 fix(chat): 前端审计修复——预览契约改HTML/状态机统一/进度错误持久化/chat_state.js抽取
- app.py: /result/preview 返回渲染 HTML(HTMLResponse) 而非 {html} JSON;新增 /chat_state.js 静态路由;预览缺失返回 404(RESULT_NOT_FOUND)
- chat.html: currentProject 统一为 draftProject;新会话继承已选项目(§4.2);上传区显隐/类型映射/抽屉脏检测改用 GenesisState;loadSession 按 role 渲染 progress/error;加 h1 标题
- chat_state.js(新): 抽取 autoBindProject/shouldHideUploadSelect/resolveUploadType/computeDrawerSnapshot/isDrawerDirty/buildWelcome 纯函数(U+1 分隔符)
- agent.py: 新增 _persist_progress/_store_error,进度与错误以 role 入库(重载可见)
- 测试: test_chat_state.js(11 passed) + test_frontend_audit_fixes.py(5) + 修正 test_server_api 旧 JSON 契约断言;全量 pytest 568 passed / 99.06%
2026-08-29 11:28:08 +08:00

52 lines
1.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 前端核心状态逻辑单测(Node 原生 test runnerUMD 模块可在 Node 下 require
// 对应方案 docs/frontend_audit_plan.md §7.1 / §4.4
const test = require('node:test');
const assert = require('node:assert/strict');
const S = require('../src/genesis/server/static/chat_state.js');
test('autoBindProject: 启动无项目且有项目时自动绑首项', () => {
assert.equal(S.autoBindProject(null, [{ name: 'A' }, { name: 'B' }]), 'A');
});
test('autoBindProject: 指向已删除项目时回退首项', () => {
assert.equal(S.autoBindProject('X', [{ name: 'A' }]), 'A');
});
test('autoBindProject: 已选有效项目保持不变', () => {
assert.equal(S.autoBindProject('A', [{ name: 'A' }]), 'A');
});
test('shouldHideUploadSelect: 未绑定任何项目时显示下拉', () => {
assert.equal(S.shouldHideUploadSelect(null, null), false);
});
test('shouldHideUploadSelect: 已绑定项目(draft 或 active)时隐藏下拉', () => {
assert.equal(S.shouldHideUploadSelect(null, 'A'), true);
assert.equal(S.shouldHideUploadSelect('A', null), true);
});
test('resolveUploadType: 绑定项目时强制 requirements', () => {
assert.equal(S.resolveUploadType(null, 'A', 'template'), 'requirements');
});
test('resolveUploadType: 未绑定项目时保留用户选择', () => {
assert.equal(S.resolveUploadType(null, null, 'template'), 'template');
});
test('computeDrawerSnapshot: 去空白并以单元分隔符连接', () => {
assert.equal(S.computeDrawerSnapshot([' a ', 'b']), 'a\u0001b');
});
test('isDrawerDirty: 快照不同为脏,相同为干净', () => {
assert.equal(S.isDrawerDirty('x', 'y'), true);
assert.equal(S.isDrawerDirty('x', 'x'), false);
});
test('buildWelcome: 无项目提示新建/选择项目', () => {
assert.match(S.buildWelcome(null), /请新建项目|选择项目/);
});
test('buildWelcome: 有项目提示由项目提供模板/规则/代码库', () => {
assert.match(S.buildWelcome('A'), /项目「A」/);
});