Files
baiyue-firstleg/scripts/admin-test-env-modules/finance-downloads-contract.test.mjs
T

74 lines
3.7 KiB
JavaScript
Raw Normal View History

2026-08-17 18:00:38 +08:00
import test from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
2026-08-17 18:32:38 +08:00
import { EXPORT_SPECS, REQUIRED_PERMISSIONS, run } from './finance-downloads.mjs'
2026-08-17 18:00:38 +08:00
import { normalizeModuleOrder } from '../admin-test-env-acceptance.mjs'
const here = path.dirname(fileURLToPath(import.meta.url))
const source = fs.readFileSync(path.join(here, 'finance-downloads.mjs'), 'utf8')
test('八类 Finance XLSX 契约均有正式表头并在完整链末尾执行', () => {
2026-08-17 18:32:38 +08:00
assert.deepEqual(REQUIRED_PERMISSIONS, [
'platform:download:list', 'platform:finance:customer-account:export',
'platform:finance:customer-arap:export', 'platform:finance:customer-statement:export',
'platform:finance:settlement-ar:export', 'platform:finance:settlement-ap:export',
])
2026-08-17 18:00:38 +08:00
assert.deepEqual(Object.keys(EXPORT_SPECS), [
'FINANCE_CUSTOMER_ACCOUNT_LIST', 'FINANCE_CUSTOMER_ACCOUNT_LEDGER', 'FINANCE_FEE_SOURCE_LIST',
'FINANCE_RECONCILIATION_STATEMENT_LIST', 'FINANCE_RECEIVABLE_SETTLEMENT_LIST',
'FINANCE_RECEIVABLE_SETTLEMENT_DETAIL', 'FINANCE_PAYABLE_SETTLEMENT_LIST',
'FINANCE_PAYABLE_SETTLEMENT_DETAIL',
])
assert.ok(Object.values(EXPORT_SPECS).every((headers) => headers.length >= 9))
const order = normalizeModuleOrder(['finance-downloads', 'finance-settlement-full'])
2026-09-04 17:17:08 +08:00
assert.deepEqual(order.slice(-5), [
'finance-full-fixtures', 'finance-reconciliation-full', 'finance-settlement-full',
'finance-direct-paid-isolation', 'finance-downloads',
2026-08-17 18:00:38 +08:00
])
})
test('验收只使用本轮 marker fixture,解析真实 XLSX 并覆盖门禁和失败信息', () => {
assert.match(source, /fixture\.marker !== context\.marker/)
assert.match(source, /parseXlsx\(download\.bytes\)/)
assert.match(source, /processedRows/)
assert.match(source, /60 秒同参请求合并/)
assert.match(source, /同用户并发导出门禁/)
assert.match(source, /无 Finance export 权限拒绝创建/)
assert.match(source, /Provider 失败信息可见/)
assert.match(source, /9223372036854775806/)
assert.match(source, /find\(\(item\) => item\?\.direction === 'RECEIVABLE'\)/)
2026-08-17 18:00:38 +08:00
assert.doesNotMatch(source, /exportType:\s*['"]CUSTOMER_LIST/)
2026-08-20 17:00:05 +08:00
assert.doesNotMatch(source, /FINANCE_FEE_SOURCE_LIST:[^\n]*参与结算/)
2026-08-17 18:00:38 +08:00
})
test('未部署时能力探测后记录部署前置,不借历史业务数据', async () => {
const steps = []; const gaps = []
const context = {
marker: 'ADMIN-API-PROBE', createdResources: {},
2026-08-17 18:32:38 +08:00
apiSuccess(module, name, response) {
const passed = response.http === 200 && String(response.body?.code) === '200'
steps.push({ module, name, passed }); return passed ? response.body.data : null
},
2026-08-17 18:00:38 +08:00
assert(module, name) { steps.push({ module, name, passed: false }) },
addStep(module, name, response, passed, evidence, options) { steps.push({ module, name, passed, evidence, options }) },
addCoverageGap(...args) { gaps.push(args) },
2026-08-17 18:32:38 +08:00
async request(method, path) {
if (path.endsWith('/authorization/permissions')) return { http: 200, body: { code: '200', data: REQUIRED_PERMISSIONS } }
return { http: 200, body: { code: 'A0403', message: 'not deployed' } }
},
2026-08-17 18:00:38 +08:00
}
await run(context)
assert.equal(context.createdResources.financeExportTasks.marker, context.marker)
assert.equal(gaps.length, 1)
assert.match(gaps[0][3], /部署后重跑完整链/)
assert.equal(steps.some((step) => step.name === '读取客户账户筛选事实'), false)
})
2026-10-20 14:22:53 +08:00
test('同参导出只合并进行中任务,已完成任务允许按同参重新导出', () => {
assert.match(source, /60 秒同参请求合并/)
assert.match(source, /String\(originalStatus\) === 'SUCCEEDED'/)
assert.match(source, /File 只合并 PENDING\/RUNNING 的同参任务/)
})