Files
X-Financial/web/tests/requestProgressSteps.test.mjs

183 lines
6.0 KiB
JavaScript
Raw Normal View History

import assert from 'node:assert/strict'
import test from 'node:test'
import { mapExpenseClaimToRequest } from '../src/composables/useRequests.js'
test('progress steps show approval operator time and current stay duration', () => {
const originalNow = Date.now
Date.now = () => new Date('2026-05-20T05:00:00.000Z').getTime()
try {
const request = mapExpenseClaimToRequest({
id: 'claim-1',
claim_no: 'EXP-202605-001',
employee_name: '张三',
department_name: '市场部',
expense_type: 'transport',
reason: '交通报销',
location: '上海',
amount: 88,
invoice_count: 1,
occurred_at: '2026-05-20T01:00:00.000Z',
submitted_at: '2026-05-20T02:00:00.000Z',
created_at: '2026-05-20T01:30:00.000Z',
updated_at: '2026-05-20T03:30:00.000Z',
status: 'submitted',
approval_stage: '财务审批',
risk_flags_json: [
{
source: 'manual_approval',
operator: '李经理',
previous_approval_stage: '直属领导审批',
next_approval_stage: '财务审批',
created_at: '2026-05-20T03:30:00.000Z'
}
],
items: []
})
const leaderStep = request.progressSteps.find((step) => step.label === '直属领导审批')
const financeStep = request.progressSteps.find((step) => step.label === '财务审批')
const aiStep = request.progressSteps.find((step) => step.label === 'AI预审')
const firstStep = request.progressSteps[0]
assert.equal(firstStep.label, '创建单据')
assert.equal(leaderStep.time, '李经理通过')
assert.match(leaderStep.detail, /2026-05-20/)
assert.match(leaderStep.title, /李经理审批通过/)
assert.equal(aiStep.time, 'AI预审通过')
assert.match(aiStep.detail, /2026-05-20/)
assert.equal(financeStep.current, true)
assert.equal(financeStep.time, '停留 1小时30分钟')
} finally {
Date.now = originalNow
}
})
test('progress steps do not expose approver email when manager name is available', () => {
const originalNow = Date.now
Date.now = () => new Date('2026-05-20T05:00:00.000Z').getTime()
try {
const request = mapExpenseClaimToRequest({
id: 'claim-email-operator',
claim_no: 'EXP-202605-003',
employee_name: '张三',
department_name: '市场部',
manager_name: '李经理',
expense_type: 'transport',
reason: '交通报销',
location: '上海',
amount: 88,
invoice_count: 1,
occurred_at: '2026-05-20T01:00:00.000Z',
submitted_at: '2026-05-20T02:00:00.000Z',
created_at: '2026-05-20T01:30:00.000Z',
updated_at: '2026-05-20T03:30:00.000Z',
status: 'submitted',
approval_stage: '财务审批',
risk_flags_json: [
{
source: 'manual_approval',
operator: 'manager@example.com',
operator_username: 'manager@example.com',
previous_approval_stage: '直属领导审批',
next_approval_stage: '财务审批',
created_at: '2026-05-20T03:30:00.000Z'
}
],
items: []
})
const leaderStep = request.progressSteps.find((step) => step.label === '直属领导审批')
assert.equal(leaderStep.time, '李经理通过')
assert.ok(!leaderStep.title.includes('manager@example.com'))
} finally {
Date.now = originalNow
}
})
test('completed finance approval marks finance and archive progress steps', () => {
const request = mapExpenseClaimToRequest({
id: 'claim-finance-completed',
claim_no: 'EXP-202605-004',
employee_name: '张三',
department_name: '市场部',
expense_type: 'transport',
reason: '交通报销',
location: '上海',
amount: 88,
invoice_count: 1,
occurred_at: '2026-05-20T01:00:00.000Z',
submitted_at: '2026-05-20T02:00:00.000Z',
created_at: '2026-05-20T01:30:00.000Z',
updated_at: '2026-05-20T04:00:00.000Z',
status: 'approved',
approval_stage: '归档入账',
risk_flags_json: [
{
source: 'manual_approval',
operator: '李经理',
previous_approval_stage: '直属领导审批',
next_approval_stage: '财务审批',
created_at: '2026-05-20T03:00:00.000Z'
},
{
source: 'finance_approval',
operator: '财务复核',
previous_approval_stage: '财务审批',
next_approval_stage: '归档入账',
created_at: '2026-05-20T04:00:00.000Z'
}
],
items: []
})
const financeStep = request.progressSteps.find((step) => step.label === '财务审批')
const archiveStep = request.progressSteps.find((step) => step.label === '归档入账')
assert.equal(request.workflowNode, '归档入账')
assert.equal(financeStep.time, '财务复核通过')
assert.match(financeStep.detail, /2026-05-20/)
assert.equal(archiveStep.time, '归档入账')
assert.equal(archiveStep.done, true)
})
test('current direct manager step shows how long the claim has stayed there', () => {
const originalNow = Date.now
Date.now = () => new Date('2026-05-20T05:15:00.000Z').getTime()
try {
const request = mapExpenseClaimToRequest({
id: 'claim-2',
claim_no: 'EXP-202605-002',
employee_name: '王五',
department_name: '市场部',
expense_type: 'office',
reason: '办公用品',
location: '上海',
amount: 128,
invoice_count: 1,
occurred_at: '2026-05-20T01:00:00.000Z',
submitted_at: '2026-05-20T02:00:00.000Z',
created_at: '2026-05-20T01:30:00.000Z',
updated_at: '2026-05-20T02:00:00.000Z',
status: 'submitted',
approval_stage: '直属领导审批',
risk_flags_json: [],
items: []
})
const leaderStep = request.progressSteps.find((step) => step.label === '直属领导审批')
const submitStep = request.progressSteps.find((step) => step.label === '待提交')
assert.equal(submitStep.time, '王五提交')
assert.match(submitStep.detail, /2026-05-20/)
assert.equal(leaderStep.current, true)
assert.equal(leaderStep.time, '停留 3小时15分钟')
} finally {
Date.now = originalNow
}
})