130 lines
5.2 KiB
TypeScript
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');
|
|
});
|
|
});
|