- 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%
52 lines
1.9 KiB
JavaScript
52 lines
1.9 KiB
JavaScript
// 前端核心状态逻辑单测(Node 原生 test runner,UMD 模块可在 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」/);
|
||
});
|