Files
Agent-System/web/src/tests/urs-private-shared.test.ts
T

130 lines
5.2 KiB
TypeScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import seed from '../data/seeds/tenProjectsSeed.json';
import { markdownToBlockAST } from '../engine/markdownToBlock';
import { DeliverableItem } from '../types/workbench';
describe('用户上传文档私密归档与共享流转测试', () => {
it('10 个评审项目均包含已共享的 URS 交付物与 AST,支持跨角色合规查阅且会话均以 assistant 闭环', () => {
assert.equal(seed.projects.length, 10);
seed.projects.forEach((proj: any) => {
const pid = proj.id;
const expectedDocId = `doc-proj${pid}-urs`;
// 1. 检查 deliverables
const deliv = seed.deliverables.find((d: any) => d.projectId === pid && d.docId === expectedDocId);
assert.ok(deliv, `项目 ${pid} 必须存在 URS 交付物`);
assert.equal(deliv.category, 'shared', '张工上传后已共享至项目协作参考库');
assert.equal(deliv.space, 'project_shared', '必须在项目共享参考空间');
assert.equal(deliv.creatorId, 1, '编制人必须为张工 (id=1)');
// 2. 检查 documents (AST)
const doc = (seed.documents as any)[expectedDocId];
assert.ok(doc, `项目 ${pid} 必须存在 URS AST 文档`);
assert.equal(doc.category, 'shared');
assert.equal(doc.space, 'project_shared');
assert.ok(doc.markdown.length > 500, 'URS Markdown 必须包含详实的临床与工程标准内容');
assert.match(doc.markdown, /用户需求说明书|URS|GB 9706|临床痛点/);
// 3. 检查聊天第一轮附件
const attachedMsg = seed.messages.find((m: any) =>
m.attachments && m.attachments.some((a: any) => a.docId === expectedDocId)
);
assert.ok(attachedMsg, `项目 ${pid} 第一轮对话必须包含带 docId 的 URS 附件`);
});
// 4. 验证会话终态:所有会话必须以 assistant 消息闭环
seed.sessions.forEach((sess: any) => {
const sessMsgs = seed.messages.filter((m: any) => m.sessionId === sess.sessionId);
assert.ok(sessMsgs.length > 0, `会话 ${sess.sessionId} 消息数不能为空`);
const lastMsg = sessMsgs[sessMsgs.length - 1];
assert.equal(lastMsg.role, 'assistant', `会话 ${sess.sessionId} 最后一条消息必须为 assistant 闭环回复`);
});
// 5. 验证自然语气:绝不能存在机械报号与生硬套话
seed.messages.forEach((m: any) => {
assert.ok(!m.content.includes('我是审核人李主管'), `不得出现生硬自我介绍: ${m.content}`);
assert.ok(!m.content.includes('我是批准人王总监'), `不得出现生硬自我介绍: ${m.content}`);
});
});
it('用户上传附件自动生成私密交付物并在 AST 中建立隔离,支持流转至项目参考库', () => {
const uploadedAtt = {
name: '微创器械用户需求调研报告.docx',
size: '1.8 MB',
type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
};
const fileDocId = `doc-upload-test-1`;
const baseTitle = uploadedAtt.name.replace(/\.[^/.]+$/, '');
const currentProjectId = 6001;
const currentUserId = 1;
const currentUserName = '张工';
const newDeliverable: DeliverableItem = {
docId: fileDocId,
projectId: currentProjectId,
taskKey: 'user_requirements',
title: baseTitle,
stage: 'V0.5',
category: 'private',
creatorId: currentUserId,
creatorName: currentUserName,
isFixedWorkflow: false,
isTemplateOnly: false,
lifecycleState: 'drafting',
isClaimed: true,
author: currentUserName,
reviewer: '李主管',
approver: '王总监',
updatedAt: '2026-09-11',
summary: `用户上传的私密需求文档《${uploadedAtt.name}》`,
space: 'my_private',
governanceMode: 'freeform',
};
const initialMd = `# ${baseTitle}\n\n> 上传人:${currentUserName}\n\n## 1. 文档概述\n\n临床科室实际需求。`;
const ast = markdownToBlockAST(initialMd, {
docId: fileDocId,
title: baseTitle,
taskKey: 'user_requirements',
version: 'V1.0',
category: 'private',
creatorId: currentUserId,
creatorName: currentUserName,
lifecycleState: 'drafting',
isClaimed: true,
author: currentUserName,
reviewer: '李主管',
approver: '王总监',
});
ast.governanceMode = 'freeform';
ast.space = 'my_private';
assert.equal(newDeliverable.category, 'private');
assert.equal(newDeliverable.space, 'my_private');
assert.equal(ast.category, 'private');
assert.equal(ast.space, 'my_private');
// 模拟一键共享给项目组
newDeliverable.category = 'shared';
newDeliverable.space = 'project_shared';
ast.category = 'shared';
ast.space = 'project_shared';
assert.equal(newDeliverable.category, 'shared');
assert.equal(newDeliverable.space, 'project_shared');
assert.equal(ast.category, 'shared');
assert.equal(ast.space, 'project_shared');
// 模拟撤回为个人私密
newDeliverable.category = 'private';
newDeliverable.space = 'my_private';
ast.category = 'private';
ast.space = 'my_private';
assert.equal(newDeliverable.category, 'private');
assert.equal(newDeliverable.space, 'my_private');
});
});