- useWorkbenchAiApplicationPreviewFlow/useWorkbenchAiActionRouter/useWorkbenchAiCommandIntents 支持 task1 完成后自动推进 task2,确认按钮直接拉起申请预览,草稿/提交成功后继续推进下一 task - workbenchAiIntentPlannerModel/workbenchAiMessageModel/workbenchAiCommandIntentModel 适配多 task 意图规划与消息结构 - aiApplicationPreviewActions/aiApplicationPrecheckModel/aiExpenseDraftModel/aiWorkbenchConversationStore 草稿与会话存储适配 - PersonalWorkbenchAiMode 与样式适配,更新 preview-actions/expense-draft/conversation-store/fast-preview/action-router/command-intent/intent-planner 测试
113 lines
4.1 KiB
JavaScript
113 lines
4.1 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import {
|
|
applyAiExpenseAnswer,
|
|
buildAiExpenseDraftPrefillValues,
|
|
buildAiExpenseStepPrompt,
|
|
buildAiExpenseSummary,
|
|
createAiExpenseDraft,
|
|
getAiExpenseCurrentStep,
|
|
isAiExpenseDraftComplete
|
|
} from '../src/utils/aiExpenseDraftModel.js'
|
|
|
|
test('draft starts at the reason step regardless of expense type', () => {
|
|
const draft = createAiExpenseDraft('transport', '交通费')
|
|
assert.equal(draft.expenseType, 'transport')
|
|
assert.equal(draft.expenseTypeLabel, '交通费')
|
|
assert.equal(draft.stepKey, 'reason')
|
|
assert.equal(getAiExpenseCurrentStep(draft).key, 'reason')
|
|
})
|
|
|
|
test('answers advance through fields in order and reach the summary step', () => {
|
|
let draft = createAiExpenseDraft('office', '办公用品费')
|
|
draft = applyAiExpenseAnswer(draft, '项目现场临时采购', [])
|
|
assert.equal(draft.stepKey, 'time_range')
|
|
draft = applyAiExpenseAnswer(draft, '2026-06-15', [])
|
|
assert.equal(draft.stepKey, 'location')
|
|
draft = applyAiExpenseAnswer(draft, '京东', [])
|
|
assert.equal(draft.stepKey, 'amount')
|
|
draft = applyAiExpenseAnswer(draft, '320元', [])
|
|
assert.equal(draft.stepKey, 'attachments')
|
|
draft = applyAiExpenseAnswer(draft, '稍后上传', [])
|
|
assert.ok(isAiExpenseDraftComplete(draft))
|
|
})
|
|
|
|
test('attachments step collects uploaded file names', () => {
|
|
let draft = createAiExpenseDraft('office', '办公用品费')
|
|
draft = applyAiExpenseAnswer(draft, '事由', [])
|
|
draft = applyAiExpenseAnswer(draft, '2026-06-15', [])
|
|
draft = applyAiExpenseAnswer(draft, '京东', [])
|
|
draft = applyAiExpenseAnswer(draft, '320元', [])
|
|
draft = applyAiExpenseAnswer(draft, '', [{ name: '发票.pdf' }])
|
|
assert.deepEqual(draft.values.attachment_names, ['发票.pdf'])
|
|
assert.ok(isAiExpenseDraftComplete(draft))
|
|
})
|
|
|
|
test('step prompt names the type and the current field', () => {
|
|
const draft = createAiExpenseDraft('transport', '交通费')
|
|
const prompt = buildAiExpenseStepPrompt(draft)
|
|
assert.match(prompt, /交通费/)
|
|
assert.match(prompt, /事由/)
|
|
})
|
|
|
|
test('summary lists every filled field and the linked application', () => {
|
|
let draft = createAiExpenseDraft('transport', '交通费')
|
|
draft = {
|
|
...draft,
|
|
applicationClaim: {
|
|
application_claim_no: 'AP-202606-001',
|
|
application_reason: '送客户去机场',
|
|
application_business_time: '2026-06-15',
|
|
application_location: '公司至机场'
|
|
}
|
|
}
|
|
draft = applyAiExpenseAnswer(draft, '送客户去机场', [])
|
|
draft = applyAiExpenseAnswer(draft, '2026-06-15', [])
|
|
draft = applyAiExpenseAnswer(draft, '公司至机场', [])
|
|
draft = applyAiExpenseAnswer(draft, '85元', [])
|
|
draft = applyAiExpenseAnswer(draft, '稍后上传', [])
|
|
const summary = buildAiExpenseSummary(draft)
|
|
assert.match(summary, /交通费/)
|
|
assert.match(summary, /AP-202606-001/)
|
|
assert.match(summary, /85元/)
|
|
})
|
|
|
|
test('buildAiExpenseDraftPrefillValues maps task ontology fields onto draft fields', () => {
|
|
const values = buildAiExpenseDraftPrefillValues({
|
|
expense_type: 'meal',
|
|
amount: '2000元',
|
|
time_range: '昨天',
|
|
reason: '客户招待',
|
|
location: '上海',
|
|
unrelated_field: 'ignore me'
|
|
})
|
|
assert.equal(values.amount, '2000元')
|
|
assert.equal(values.time_range, '昨天')
|
|
assert.equal(values.reason, '客户招待')
|
|
assert.equal(values.location, '上海')
|
|
assert.equal(values.unrelated_field, undefined)
|
|
})
|
|
|
|
test('createAiExpenseDraft with prefillValues skips already filled steps', () => {
|
|
const draft = createAiExpenseDraft('meal', '业务招待费', {
|
|
amount: '2000元',
|
|
reason: '客户招待'
|
|
})
|
|
// reason 已填,跳到下一个未填字段 time_range
|
|
assert.equal(draft.values.amount, '2000元')
|
|
assert.equal(draft.values.reason, '客户招待')
|
|
assert.equal(draft.stepKey, 'time_range')
|
|
})
|
|
|
|
test('createAiExpenseDraft with all prefillValues lands on summary', () => {
|
|
const draft = createAiExpenseDraft('meal', '业务招待费', {
|
|
reason: '客户招待',
|
|
time_range: '昨天',
|
|
location: '上海',
|
|
amount: '2000元',
|
|
attachments: '稍后上传'
|
|
})
|
|
assert.ok(isAiExpenseDraftComplete(draft))
|
|
})
|