114 lines
4.1 KiB
TypeScript
114 lines
4.1 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
classifyRejectUtterance,
|
|
resolveDocGovCard,
|
|
canConfirmReject,
|
|
} from './cardActionPolicy';
|
|
|
|
test('classifyRejectUtterance: 询问原因 → QUERY_REJECT_REASON', () => {
|
|
assert.equal(
|
|
classifyRejectUtterance('注册路径可行性评估报告被驳回的原因是什么'),
|
|
'QUERY_REJECT_REASON'
|
|
);
|
|
assert.equal(classifyRejectUtterance('为什么被退回了'), 'QUERY_REJECT_REASON');
|
|
assert.equal(classifyRejectUtterance('驳回意见是什么'), 'QUERY_REJECT_REASON');
|
|
});
|
|
|
|
test('classifyRejectUtterance: 明确执行 → EXECUTE_REJECT', () => {
|
|
assert.equal(
|
|
classifyRejectUtterance('把调研报告审核驳回,意见为:缺少抗扰度指标'),
|
|
'EXECUTE_REJECT'
|
|
);
|
|
assert.equal(classifyRejectUtterance('请驳回这份文档'), 'EXECUTE_REJECT');
|
|
assert.equal(classifyRejectUtterance('终审驳回,意见:资料不全'), 'EXECUTE_REJECT');
|
|
});
|
|
|
|
test('classifyRejectUtterance: 模糊 → OTHER', () => {
|
|
assert.equal(classifyRejectUtterance('驳回了吗'), 'OTHER');
|
|
assert.equal(classifyRejectUtterance('今天天气不错'), 'OTHER');
|
|
});
|
|
|
|
test('resolveDocGovCard: 编制人查询 → 信息卡且无 confirm_reject', () => {
|
|
const res = resolveDocGovCard({
|
|
role: 'author',
|
|
lifecycleState: 'drafting',
|
|
utteranceIntent: 'QUERY_REJECT_REASON',
|
|
docId: 'doc-feas',
|
|
docTitle: '注册路径可行性评估报告',
|
|
latestRejectReason: '缺少 YY 9706.102 电磁兼容专项与听神经保护方案,退回修改',
|
|
});
|
|
assert.equal(res.kind, 'reject_reason_info');
|
|
assert.ok(res.card);
|
|
assert.equal(res.card!.cardType, 'REMINDER_NOTICE');
|
|
assert.ok(!res.card!.actions.some((a) => a.actionId === 'confirm_reject'));
|
|
assert.ok(res.card!.actions.some((a) => a.actionId === 'ack_reject_reason'));
|
|
assert.ok(res.card!.actions.some((a) => a.actionId === 'start_revision'));
|
|
assert.ok(res.replyContent.includes('YY 9706.102'));
|
|
});
|
|
|
|
test('resolveDocGovCard: 审核人执行 + reviewing → 确认卡', () => {
|
|
const res = resolveDocGovCard({
|
|
role: 'reviewer',
|
|
lifecycleState: 'reviewing',
|
|
utteranceIntent: 'EXECUTE_REJECT',
|
|
docId: 'doc-002',
|
|
docTitle: '竞品调研',
|
|
latestRejectReason: '缺少抗扰度指标',
|
|
});
|
|
assert.equal(res.kind, 'reject_confirm_review');
|
|
assert.ok(res.card);
|
|
assert.equal(res.card!.cardType, 'CONFIRMATION');
|
|
const confirm = res.card!.actions.find((a) => a.actionId === 'confirm_reject');
|
|
assert.ok(confirm);
|
|
assert.equal(confirm!.label, '确认驳回退回编制');
|
|
assert.equal(res.card!.actions.find((a) => a.actionId === 'cancel')?.label, '放弃驳回');
|
|
});
|
|
|
|
test('resolveDocGovCard: 编制人误说执行驳回 → 无权纯文本', () => {
|
|
const res = resolveDocGovCard({
|
|
role: 'author',
|
|
lifecycleState: 'reviewing',
|
|
utteranceIntent: 'EXECUTE_REJECT',
|
|
docId: 'doc-feas',
|
|
docTitle: '可行性报告',
|
|
});
|
|
assert.equal(res.kind, 'deny_text');
|
|
assert.equal(res.card, undefined);
|
|
assert.ok(res.replyContent.includes('不具备'));
|
|
});
|
|
|
|
test('resolveDocGovCard: 批准人 + approving → 终审确认卡', () => {
|
|
const res = resolveDocGovCard({
|
|
role: 'approver',
|
|
lifecycleState: 'approving',
|
|
utteranceIntent: 'EXECUTE_REJECT',
|
|
docId: 'doc-003',
|
|
docTitle: '终审稿',
|
|
latestRejectReason: '临床证据不足',
|
|
});
|
|
assert.equal(res.kind, 'reject_confirm_final');
|
|
assert.equal(res.card?.title, '终审驳回确认');
|
|
});
|
|
|
|
test('resolveDocGovCard: 编制人 OTHER → 引导查询无危险按钮', () => {
|
|
const res = resolveDocGovCard({
|
|
role: 'author',
|
|
lifecycleState: 'drafting',
|
|
utteranceIntent: 'OTHER',
|
|
docId: 'doc-feas',
|
|
docTitle: '可行性报告',
|
|
latestRejectReason: '缺 EMC',
|
|
});
|
|
assert.equal(res.kind, 'deny_text');
|
|
assert.equal(res.card, undefined);
|
|
assert.ok(res.replyContent.includes('编制'));
|
|
});
|
|
|
|
test('canConfirmReject: 仅审核/批准', () => {
|
|
assert.equal(canConfirmReject('author'), false);
|
|
assert.equal(canConfirmReject('viewer'), false);
|
|
assert.equal(canConfirmReject('reviewer'), true);
|
|
assert.equal(canConfirmReject('approver'), true);
|
|
});
|