74 lines
3.7 KiB
JavaScript
74 lines
3.7 KiB
JavaScript
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'
|
|
import { EXPORT_SPECS, REQUIRED_PERMISSIONS, run } from './finance-downloads.mjs'
|
|
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 契约均有正式表头并在完整链末尾执行', () => {
|
|
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',
|
|
])
|
|
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'])
|
|
assert.deepEqual(order.slice(-5), [
|
|
'finance-full-fixtures', 'finance-reconciliation-full', 'finance-settlement-full',
|
|
'finance-direct-paid-isolation', 'finance-downloads',
|
|
])
|
|
})
|
|
|
|
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'\)/)
|
|
assert.doesNotMatch(source, /exportType:\s*['"]CUSTOMER_LIST/)
|
|
assert.doesNotMatch(source, /FINANCE_FEE_SOURCE_LIST:[^\n]*参与结算/)
|
|
})
|
|
|
|
test('未部署时能力探测后记录部署前置,不借历史业务数据', async () => {
|
|
const steps = []; const gaps = []
|
|
const context = {
|
|
marker: 'ADMIN-API-PROBE', createdResources: {},
|
|
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
|
|
},
|
|
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) },
|
|
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' } }
|
|
},
|
|
}
|
|
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)
|
|
})
|
|
|
|
test('同参导出只合并进行中任务,已完成任务允许按同参重新导出', () => {
|
|
assert.match(source, /60 秒同参请求合并/)
|
|
assert.match(source, /String\(originalStatus\) === 'SUCCEEDED'/)
|
|
assert.match(source, /File 只合并 PENDING\/RUNNING 的同参任务/)
|
|
})
|