Files
baiyue-firstleg/scripts/acceptance-finance-full-contract.test.mjs
T

78 lines
3.9 KiB
JavaScript
Raw Normal View History

2026-08-12 10:59:39 +08:00
import test from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import http from 'node:http'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
2026-09-04 16:20:09 +08:00
import { AcceptanceRun, normalizeModuleOrder } from './admin-test-env-acceptance.mjs'
2026-08-12 10:59:39 +08:00
const here = path.dirname(fileURLToPath(import.meta.url))
const source = fs.readFileSync(path.join(here, 'admin-test-env-acceptance.mjs'), 'utf8')
test('默认全量按新财务链执行直接收付款隔离且不包含旧 finance', () => {
2026-08-17 18:00:38 +08:00
const match = source.match(/const CONFIGURED_MODULES = \[(.*?)\]/s)
2026-08-12 10:59:39 +08:00
assert.ok(match)
const modules = [...match[1].matchAll(/'([^']+)'/g)].map((item) => item[1])
2026-08-17 18:00:38 +08:00
const financeStart = modules.indexOf('finance-full-fixtures')
2026-09-04 16:06:47 +08:00
assert.deepEqual(modules.slice(financeStart, financeStart + 5), [
2026-09-04 17:17:08 +08:00
'finance-full-fixtures', 'finance-reconciliation-full', 'finance-settlement-full',
'finance-direct-paid-isolation', 'finance-downloads',
2026-09-04 16:06:47 +08:00
])
2026-09-04 15:44:00 +08:00
assert.equal(modules.includes('finance'), false)
2026-08-12 10:59:39 +08:00
assert.match(source, /fullFinanceChain/)
2026-09-04 16:20:09 +08:00
const normalized = normalizeModuleOrder(modules)
const normalizedFinanceStart = normalized.indexOf('finance-full-fixtures')
assert.deepEqual(normalized.slice(normalizedFinanceStart, normalizedFinanceStart + 5), [
2026-09-04 17:17:08 +08:00
'finance-full-fixtures', 'finance-reconciliation-full', 'finance-settlement-full',
'finance-direct-paid-isolation', 'finance-downloads',
2026-09-04 16:20:09 +08:00
])
2026-08-12 10:59:39 +08:00
})
2026-09-04 17:17:08 +08:00
test('binary GET retries transient transport failures without retrying writes', () => {
assert.match(source, /async requestBinary\([\s\S]*?const maxAttempts = \['GET', 'HEAD'\]/)
assert.match(source, /async requestBinary\([\s\S]*?attempt < maxAttempts/)
})
2026-08-12 10:59:39 +08:00
test('multipart request preserves FormData boundary and unified response evidence', () => {
assert.match(source, /async requestMultipart\(/)
assert.match(source, /form\.append\('file'/)
assert.match(source, /body instanceof FormData \? body : JSON\.stringify\(body\)/)
assert.doesNotMatch(source, /requestMultipart[\s\S]{0,500}Content-Type.*multipart/i)
})
test('multipart helper sends the File upload contract and parses unified evidence', async (t) => {
let received = null
const server = http.createServer((request, response) => {
const chunks = []
request.on('data', (chunk) => chunks.push(chunk))
request.on('end', () => {
received = { headers: request.headers, body: Buffer.concat(chunks).toString('latin1') }
response.writeHead(200, { 'Content-Type': 'application/json', 'X-Request-Id': 'request-1', 'X-Trace-Id': 'trace-1' })
response.end(JSON.stringify({ code: '200', data: { fileId: '9' } }))
})
})
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve))
t.after(() => server.close())
const address = server.address()
const run = new AcceptanceRun({ gateway: `http://127.0.0.1:${address.port}` })
run.token = 'contract-token'
const result = await run.requestMultipart('POST', '/api/platform/finance/v1/vouchers?customerId=7', {
name: 'voucher.txt', type: 'text/plain', content: new TextEncoder().encode('voucher fixture'),
})
assert.equal(result.http, 200)
assert.equal(result.body.data.fileId, '9')
assert.equal(result.requestId, 'request-1')
assert.equal(result.traceId, 'trace-1')
assert.equal(received.headers.authorization, 'Bearer contract-token')
assert.match(received.headers['content-type'], /^multipart\/form-data; boundary=/)
assert.match(received.body, /name="file"; filename="voucher\.txt"/)
assert.match(received.body, /voucher fixture/)
})
test('module failures, coverage gaps and deployment blockers remain report surfaces', () => {
for (const field of ['this.modules.push', 'coverageGaps', 'deploymentBlockers']) assert.match(source, new RegExp(field.replace('.', '\\.'), 's'))
assert.match(source, /async executeModule\(name, handler\)/)
assert.match(source, /const extension = await import\(new URL\(`\.\/admin-test-env-modules\/\$\{module\}/)
})