2026-08-28 16:54:16 +08:00
|
|
|
import assert from 'node:assert/strict'
|
|
|
|
|
import { readFileSync } from 'node:fs'
|
|
|
|
|
import test from 'node:test'
|
|
|
|
|
|
|
|
|
|
const source = readFileSync(new URL('./customs.ts', import.meta.url), 'utf8')
|
|
|
|
|
const httpTypes = readFileSync(new URL('../../../api/types.ts', import.meta.url), 'utf8')
|
|
|
|
|
const httpSource = readFileSync(new URL('../../../api/http.ts', import.meta.url), 'utf8')
|
|
|
|
|
|
|
|
|
|
test('maps only the frozen merchant container-customs contract', () => {
|
|
|
|
|
assert.match(source, /type MerchantCustomsStatus = 'WAITING_UPLOAD' \| 'DOCUMENT_UPLOADED' \| 'DECLARING' \| 'CUSTOMS_COMPLETED'/)
|
|
|
|
|
assert.match(source, /inboundId: string/)
|
|
|
|
|
assert.match(source, /orderId: string/)
|
|
|
|
|
assert.match(source, /documentId: string/)
|
|
|
|
|
assert.match(source, /loadingPlanId: string/)
|
2026-08-28 17:27:12 +08:00
|
|
|
assert.match(source, /getMerchantCustomsForOrder\(orderId: string\)/)
|
|
|
|
|
assert.doesNotMatch(source, /number \| string/)
|
2026-08-28 16:54:16 +08:00
|
|
|
assert.match(source, /url: `\/merchant\/v1\/customs\/orders\/\$\{encodedId\(orderId\)\}`/)
|
|
|
|
|
assert.doesNotMatch(source, /customs\/cases|MerchantCustomsCaseDetail|getMerchantCustomsByOrder/)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('sends multi-inbound scope, optimistic versions and idempotency for every write', () => {
|
|
|
|
|
assert.match(source, /params\.append\('inboundIds', id\)/)
|
|
|
|
|
assert.match(source, /expectedVersion: document\.source\.version/)
|
|
|
|
|
assert.match(source, /params: \{ expectedVersion: document\.source\.version \}/)
|
2026-09-26 12:08:28 +08:00
|
|
|
assert.equal(source.match(/'Idempotency-Key'/g)?.length, 6)
|
2026-08-28 16:54:16 +08:00
|
|
|
assert.match(source, /data\.append\('file', file\)/)
|
|
|
|
|
assert.match(source, /file\.size > MAX_CUSTOMS_FILE_SIZE/)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('preserves request and trace identifiers on API errors', () => {
|
|
|
|
|
assert.match(httpTypes, /readonly requestId\?: string \| null/)
|
|
|
|
|
assert.match(httpSource, /envelope\.traceId, envelope\.requestId/)
|
|
|
|
|
assert.match(source, /interface ApiErrorMeta/)
|
|
|
|
|
assert.match(source, /requestId: error\.requestId \?\? null/)
|
|
|
|
|
assert.match(source, /traceId: error\.traceId \?\? null/)
|
|
|
|
|
})
|