test(overseas): align phase four to five acceptance contracts

This commit is contained in:
2026-09-02 15:43:11 +08:00
parent 137e4e7c60
commit ef74579f2c
2 changed files with 20 additions and 9 deletions
@@ -17,11 +17,11 @@ test('current-marker departure batch proves operational documents photos customs
assert.match(customs, new RegExp(type))
}
for (const evidence of ['上传', '回读', '完成']) assert.match(documents, new RegExp(evidence))
assert.match(customs, /只读复核前置模块已完成的整柜作业资料/)
assert.match(customs, /整柜聚合回显四类当前资料与真实PDA照片证据/)
assert.match(customs, /photos\.length >= 5/)
assert.match(customs, /\/customs\/loading-plans/)
assert.match(customs, /complete-all-buy/)
assert.match(customs, /正式整柜报关聚合必须完成后才允许进入出仓确认/)
assert.match(customs, /四类整柜资料必须完成后才允许进入出仓确认/)
assert.match(outbound, /CUSTOMS_CLEARANCE/)
assert.match(outbound, /拖车与独立船期仅作聚合参考且不参与出仓门禁/)
assert.match(outbound, /\$\{BASE\}\/\$\{encodeURIComponent\(containerBookingId\)\}\/confirm/)
@@ -50,8 +50,8 @@ test('outbound-created query supports automated or manual carrier then reaches P
assert.match(pda, /last-leg\/inbound-plans\/convert-container/)
assert.match(pda, /Number\(summary\?\.missingInboundCodeCount\) === 0/)
assert.doesNotMatch(pda, /summary\?\.eligible/)
assert.match(pda, /item\?\.shippingReady === true/)
assert.match(pda, /nonBlank\(item\?\.carrierScheduleQueryId\)/)
assert.match(pda, /item\?\.shippingReady !== false/)
assert.match(pda, /nonBlank\(item\?\.resourceKey\)/)
assert.match(pda, /targetCorrelated/)
assert.match(pda, /deploymentBlocker: true/)
assert.doesNotMatch(pda, /addCoverageGap\([^\n]*PICKUP_READY/)
@@ -12,11 +12,19 @@ const source = fs.readFileSync(path.join(here, 'phase4-overseas-warehouse.mjs'),
function response(data, code = '200') { return { http: 200, body: { code, message: code === '200' ? 'success' : 'conflict', data }, requestId: 'request-test', traceId: 'trace-test' } }
function voidResponse() { return { http: 200, body: { code: '200', message: 'success' }, requestId: 'request-test', traceId: 'trace-test' } }
function page(records = []) { return { records, page: 1, size: 20, total: records.length, pages: records.length ? 1 : 0 } }
function contextFixture({ tenants = [{ id: '10001', status: 'ACTIVE' }], warehouseRecords = [{ id: '20001', status: 'ACTIVE', warehouseCode: 'LAX', warehouseName: '洛杉矶仓' }] } = {}) {
function contextFixture({ tenants = [{ id: '10001', status: 'ACTIVE' }], warehouseRecords = [{ id: '20001', status: 'ACTIVE', warehouseType: 'OVERSEAS', warehouseCode: 'LAX', warehouseName: '洛杉矶仓' }] } = {}) {
const calls = []; const steps = []; const gaps = []; let createdPallet = null; let createdLocation = null; let createdRelabel = null
const context = {
context: {}, createdResources: {}, marker: 'ACC-PHASE4-TEST', calls, steps, gaps,
async request(method, requestPath) { calls.push({ channel: 'domestic', method, path: requestPath }); return response(page(tenants)) },
async request(method, requestPath) {
calls.push({ channel: 'domestic', method, path: requestPath })
if (method === 'GET' && requestPath.startsWith('/api/platform/v1/iam/tenants?')) return response(page(tenants))
if (method === 'GET' && requestPath.startsWith('/api/platform/v1/warehouse-admin?')) return response(page(warehouseRecords))
if (method === 'GET' && requestPath.startsWith('/api/platform/v1/warehouse-admin/20001?')) return response({ warehouse: { id: '20001', warehouseType: 'OVERSEAS', status: 'ACTIVE' } })
if (method === 'POST' && requestPath === '/api/platform/v1/warehouse-admin') return response('20001')
if (method === 'PATCH' && requestPath.includes('/warehouse-admin/20001/status?')) return voidResponse()
throw new Error(`Unexpected domestic path: ${requestPath}`)
},
async requestOverseas(method, requestPath, body) {
calls.push({ channel: 'overseas', method, path: requestPath, body })
if (method === 'POST' && requestPath === '/api/platform/v1/warehouse-admin') return response('20001')
@@ -80,8 +88,10 @@ test('既有仓库场景只写本轮库位托盘与换标生命周期', () => {
const context = contextFixture()
return run(context).then(() => {
assert.ok(context.calls.length >= 12)
assert.ok(context.calls.every((call) => ['GET', 'POST', 'PUT', 'DELETE'].includes(call.method)))
assert.equal(context.calls.filter((call) => call.channel === 'domestic').length, 1)
assert.ok(context.calls.every((call) => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(call.method)))
const domesticCalls = context.calls.filter((call) => call.channel === 'domestic')
assert.ok(domesticCalls.length >= 1)
assert.ok(domesticCalls.every((call) => call.method === 'GET'))
assert.ok(context.calls.filter((call) => call.channel === 'overseas').every((call) => call.path.startsWith('/api/platform/v1/')))
const writes = context.calls.filter((call) => call.method !== 'GET')
assert.ok(writes.some((call) => call.method === 'DELETE' && call.path.includes('/locations/72002')))
@@ -103,9 +113,10 @@ test('既有仓库场景只写本轮库位托盘与换标生命周期', () => {
test('覆盖冻结的海外只读列表与有记录才查详情', async () => {
const context = contextFixture()
await run(context)
for (const pathToken of ['/last-leg/orders?', '/relabel-applications?', '/inbound-plans?', '/inventory/summary?', '/inventory/balances?', '/inventory/ledger?', '/warehouse-admin?', '/locations?', '/pallets?']) {
for (const pathToken of ['/last-leg/orders?', '/relabel-applications?', '/inbound-plans?', '/inventory/summary?', '/inventory/balances?', '/inventory/ledger?', '/locations?', '/pallets?']) {
assert.ok(context.calls.some((call) => call.channel === 'overseas' && call.path.includes(pathToken)), pathToken)
}
assert.ok(context.calls.some((call) => call.channel === 'domestic' && call.path.includes('/warehouse-admin?')), '/warehouse-admin?')
for (const detailToken of ['/orders/30001?', '/relabel-applications/RL-1?', '/inbound-plans/IP-1?', '/balances/60001/positions?', '/warehouse-admin/20001?', '/pallets/70001']) {
assert.ok(context.calls.some((call) => call.path.includes(detailToken)), detailToken)
}