Files
X-Financial/web/tests/ai-application-preview-actions.test.mjs
caoxiaozhu 304bbe1fd4 feat(web): 工作台 AI 模式报销预审与文档查询模型拆分
- 新增 aiApplicationPrecheckModel/aiDocumentQueryModel/aiApplicationPreviewActions/aiConversationHtmlRenderer 四个独立模型与服务,按职责从主组件拆出
- PersonalWorkbenchAiMode 接入拆分后的预审、文档查询与 HTML 渲染逻辑,配合 markdown 工具增强结构化展示
- 文档中心与归档筛选、风险可见性、申请预览等工具同步适配,补充对应单元测试
- 新增 AI 文档卡片背景资源
2026-06-20 10:17:37 +08:00

128 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict'
import test from 'node:test'
import {
AI_APPLICATION_ACTION_SAVE_DRAFT,
AI_APPLICATION_ACTION_SUBMIT,
buildAiApplicationPreviewActionPayload
} from '../src/services/aiApplicationPreviewActions.js'
import {
applyApplicationPolicyEstimateResult,
buildApplicationPolicyEstimateRequest,
buildLocalApplicationPreview
} from '../src/utils/expenseApplicationPreview.js'
const applicationPreview = {
fields: {
applicationType: '差旅费用申请',
applicant: '曹笑竹',
grade: 'P5',
department: '技术部',
position: '财务智能化产品经理',
managerName: '向万红',
time: '2026-02-20 至 2026-02-23',
location: '上海',
reason: '辅助国网仿生产服务器部署',
days: '4天',
transportMode: '火车',
lodgingDailyCap: '250元/天',
subsidyDailyCap: '100元/天',
transportPolicy: '按交通费用预估表暂估',
policyEstimate: '交通 720元 + 住宿 1,000元 + 补贴 400元 = 2,120元4天',
amount: '2,120元'
}
}
const currentUser = {
username: 'caoxiaozhu@xf.com',
name: '曹笑竹',
departmentName: '技术部',
position: '财务智能化产品经理',
grade: 'P5',
managerName: '向万红',
roleCodes: ['employee']
}
test('save application preview payload uses save draft action without submit wording', () => {
const payload = buildAiApplicationPreviewActionPayload({
actionType: AI_APPLICATION_ACTION_SAVE_DRAFT,
applicationPreview,
currentUser,
conversationId: 'inline-1'
})
assert.equal(payload.user_id, 'caoxiaozhu@xf.com')
assert.equal(payload.conversation_id, 'inline-1')
assert.equal(payload.context_json.session_type, 'application')
assert.equal(payload.context_json.review_action, undefined)
assert.equal(payload.context_json.application_action, 'save_draft')
assert.equal(payload.context_json.application_preview.fields.transportMode, '火车')
assert.match(payload.message, /费用申请保存草稿/)
assert.match(payload.message, /保存草稿/)
assert.doesNotMatch(payload.message, /确认提交/)
})
test('submit application preview payload keeps existing draft id for resubmission', () => {
const payload = buildAiApplicationPreviewActionPayload({
actionType: AI_APPLICATION_ACTION_SUBMIT,
applicationPreview,
currentUser,
conversationId: 'inline-1',
draftPayload: {
claim_id: 'draft-001',
claim_no: 'AP-202602200001'
}
})
assert.equal(payload.context_json.review_action, undefined)
assert.equal(payload.context_json.application_edit_claim_id, 'draft-001')
assert.equal(payload.context_json.draft_claim_id, 'draft-001')
assert.match(payload.message, /费用申请确认提交/)
assert.match(payload.message, /确认提交/)
})
test('travel application preview calculates base standards before transport mode is selected', () => {
const preview = buildLocalApplicationPreview(
'2月20-23日去上海出差辅助国网仿生产服务器部署',
{ name: '曹笑竹', grade: 'P5', location: '武汉' },
{ today: '2026-06-20' }
)
const request = buildApplicationPolicyEstimateRequest(preview, { grade: 'P5', location: '武汉' })
assert.equal(request.canCalculate, true)
assert.deepEqual(request.payload, {
days: 4,
location: '上海',
grade: 'P5',
transport_mode: null,
origin_location: '武汉',
travel_date: '2026-02-20'
})
const estimatedPreview = applyApplicationPolicyEstimateResult(preview, {
days: 4,
location: '上海',
matched_city: '上海',
grade: 'P5',
hotel_rate: 450,
hotel_amount: 1800,
total_allowance_rate: 100,
allowance_amount: 400,
transport_mode: '火车',
transport_origin: '武汉',
transport_destination: '上海',
transport_estimated_amount: 720,
total_amount: 2200,
rule_name: '公司差旅费报销规则',
rule_version: 'v1.0.0'
}, { grade: 'P5', location: '武汉' })
assert.equal(estimatedPreview.fields.transportMode, '')
assert.equal(estimatedPreview.missingFields.includes('出行方式'), true)
assert.equal(estimatedPreview.fields.lodgingDailyCap, '450元/天')
assert.equal(estimatedPreview.fields.subsidyDailyCap, '100元/天')
assert.equal(estimatedPreview.fields.transportPolicy, '选择火车、飞机或轮船后自动预估交通费用')
assert.equal(estimatedPreview.fields.policyEstimate, '交通待补充 + 住宿 1,800元 + 补贴 400元 = 2,200元4天不含交通')
assert.equal(estimatedPreview.fields.amount, '2,200元不含交通')
})