test(shipping): validate platform customer scope separately from business IDs

This commit is contained in:
2026-09-30 13:30:27 +08:00
parent 74f0d823da
commit 7f3c0690cd
2 changed files with 63 additions and 2 deletions
@@ -251,3 +251,63 @@ test('marker-owned pre-PDA chain covers idempotency conflicts through pickup-rea
const firstPageQuery = fixture.context.calls.find((item) => item.path === `${BASE}?page=1&size=20`)
assert.ok(firstPageQuery)
})
async function taskPageStructure(overrides) {
const fixture = markerOwnedContext()
const task = { ...fixture.task, ...overrides }
const checks = []
const originalRequest = fixture.context.request
fixture.context.createdResources = {}
fixture.context.request = async (method, requestPath, ...args) => {
if (method === 'GET' && requestPath === `${BASE}?page=1&size=20`) {
fixture.context.calls.push({ method, path: requestPath })
return ok({ records: [{ query: task, expired: false }], page: 1, size: 20, total: 1, pages: 1 })
}
return originalRequest(method, requestPath, ...args)
}
fixture.context.assert = (_module, name, _response, condition) => checks.push({ name, passed: Boolean(condition) })
fixture.context.addStep = (_module, name, _response, passed) => checks.push({ name, passed })
await runUntilPickupReady(fixture.context)
assert.ok(fixture.context.calls.every((call) => call.method === 'GET'))
assert.ok(checks.some((check) => check.name.includes('缺少本轮phase3出仓CarrierScheduleQuery') && !check.passed))
return checks.find((check) => check.name === '船节点分页与长ID结构稳定')?.passed
}
test('task page permits explicit platform scope zero and positive customer scopes as serialized longs', async () => {
for (const customerId of ['0', '7', CUSTOMER_ID]) {
assert.equal(await taskPageStructure({ customerId }), true, `customerId=${customerId}`)
}
})
test('task page still rejects negative, missing, numeric and noncanonical customer scopes', async () => {
for (const customerId of ['-1', '-9007199254740993002', '', '00', '01', '+0', '0.0', 'customer', null, undefined, 0, 7]) {
assert.equal(await taskPageStructure({ customerId }), false, `customerId=${String(customerId)}`)
}
})
test('allowing platform scope zero never relaxes positive long task, booking or container identifiers', async () => {
for (const field of ['id', 'oceanBookingId', 'containerBookingId']) {
for (const invalid of ['0', '0000000000000000', '09007199254740993', '-9007199254740993001', '7',
'9007199254740993.001', null, 9007199254740993]) {
assert.equal(await taskPageStructure({ customerId: '0', [field]: invalid }), false,
`${field}=${String(invalid)}`)
}
}
})
test('platform scope zero completes the same detail and manual-node lifecycle assertions without changing business identifiers', async () => {
const fixture = markerOwnedContext()
fixture.task.customerId = '0'
fixture.context.createdResources.phase3CarrierScheduleQuery.customerId = '0'
await runUntilPickupReady(fixture.context)
assert.equal(fixture.task.customerId, '0')
assert.equal(fixture.task.id, QUERY_ID)
assert.equal(fixture.task.oceanBookingId, OCEAN_ID)
assert.equal(fixture.task.containerBookingId, CONTAINER_ID)
assert.equal(fixture.task.latestActualNode, 'PICKUP_READY')
assert.equal(fixture.context.calls.filter((call) => call.method === 'POST').length, 15)
assert.ok(fixture.assertions.every((check) => check.passed))
assert.ok(fixture.steps.every((check) => check.passed))
})