test: keep overseas acceptance fixtures independent

This commit is contained in:
2026-09-09 19:16:18 +08:00
parent 30b9db9628
commit 90a0b009da
4 changed files with 29 additions and 7 deletions
@@ -8,8 +8,12 @@ const here = path.dirname(fileURLToPath(import.meta.url))
const source = fs.readFileSync(path.join(here, 'phase4-overseas-inbound-operations.mjs'), 'utf8')
test('module covers the frozen Admin inbound-plan write surface', () => {
for (const value of ['/convert', '/pallets/supplement', '/fba-appointments/batch',
for (const value of ['/container-preview', '/convert-container', '/pallets/supplement', '/fba-appointments/batch',
'/fba-appointments/${encodeURIComponent(appointmentNo)}']) assert.ok(source.includes(value), value)
assert.equal(source.includes("`${PLAN_BASE}/convert`"), false)
assert.match(source, /snapshotVersion/)
assert.match(source, /snapshotHash/)
assert.match(source, /'Idempotency-Key'/)
assert.match(source, /重复转换返回同一入仓计划/)
assert.match(source, /FBA预约同单号异载荷返回A0409/)
assert.match(source, /appointmentStatus: 'CANCELLED'/)
@@ -15,8 +15,8 @@ function query(path, values) {
}
function key(context, operation) { return `${context.marker}:P4-INBOUND:${operation}`.slice(0, 255) }
async function request(context, method, name, path, body) {
const response = await context.requestOverseas(method, path, body)
async function request(context, method, name, path, body, headers = {}) {
const response = await context.requestOverseas(method, path, body, headers)
context.addStep(MODULE, name, response, ok(response), trace(response), OPTIONS)
return ok(response) ? response.body?.data : null
}
@@ -40,9 +40,20 @@ async function inboundAdminLifecycle(context) {
`orderId=${id(order?.id) || 'missing'}, containerNo=${producer.containerNo}`, OPTIONS)
if (!order?.id) return
const convertBody = { orderId: id(order.id), customerId }
const plan = await request(context, 'POST', '尾程入仓单转换为入仓计划', `${PLAN_BASE}/convert`, convertBody)
const replay = await request(context, 'POST', '重复转换返回同一入仓计划', `${PLAN_BASE}/convert`, convertBody)
const bookingId = id(producer.containerBookingId)
const preview = await request(context, 'GET', '预览第二柜待生成入仓计划', query(`${PLAN_BASE}/container-preview`, {
sourceContainerBookingId: bookingId,
}))
const convertBody = { sourceContainerBookingId: bookingId,
snapshotVersion: Number(preview?.snapshotVersion), snapshotHash: preview?.snapshotHash }
const convertHeaders = { 'Idempotency-Key': key(context, 'convert-container') }
const plans = await request(context, 'POST', '尾程入仓单转换为入仓计划',
`${PLAN_BASE}/convert-container`, convertBody, convertHeaders)
const replayedPlans = await request(context, 'POST', '重复转换返回同一入仓计划',
`${PLAN_BASE}/convert-container`, convertBody, convertHeaders)
const plan = (plans || []).find((item) => (item?.lines || []).some((line) => id(line?.orderId) === id(order.id)))
|| plans?.[0]
const replay = (replayedPlans || []).find((item) => item?.planNo === plan?.planNo) || replayedPlans?.[0]
context.assert(MODULE, '入仓计划转换天然幂等', null,
Boolean(plan?.planNo) && replay?.planNo === plan.planNo,
`first=${plan?.planNo || 'missing'}, replay=${replay?.planNo || 'missing'}`, OPTIONS)
@@ -128,6 +128,9 @@ test('PDA module covers the container-number receiving contract and excludes out
assert.match(source, /rememberGeneratedPlans\(context, plans\)/)
assert.match(source, /resolveGeneratedPallet\(context, inbound\)/)
assert.match(source, /generatedPalletsByInbound/)
assert.match(source, /standardFba = matrix\?\.byDestinationType\?\.FBA\?\.find/)
assert.match(source, /item\?\.fulfillmentType !== 'ONE_CLICK_DROPSHIP'/)
assert.match(source, /const producers = \[dropship[\s\S]*?standardFba,/)
assert.doesNotMatch(source, /创建当前柜实收托盘|创建当前柜实收库位|async function createPallet/)
assert.match(source, /retained as acceptance evidence/)
assert.match(source, /preferredProducer\?\.cartonMarks\?\.length/)
@@ -833,7 +833,11 @@ export async function run(context) {
}
const matrix = context.createdResources?.phase4InboundProducerFixtures
const dropship = matrix?.containers?.find((item) => item?.fulfillmentType === 'ONE_CLICK_DROPSHIP')
const producers = [dropship || matrix?.byDestinationType?.FBA?.[0], matrix?.byDestinationType?.OVERSEAS?.[0]]
const standardFba = matrix?.byDestinationType?.FBA?.find((item) => item?.fulfillmentType !== 'ONE_CLICK_DROPSHIP')
// The sealed dropship pallet proves the indivisible handover. A separate standard FBA
// fixture supplies multiple cartons for reversible split/merge/unbind and relabel checks.
const producers = [dropship || matrix?.byDestinationType?.FBA?.[0], standardFba,
matrix?.byDestinationType?.OVERSEAS?.[0]]
.filter((item) => nonBlank(item?.containerNo))
const allProducers = Array.isArray(matrix?.containers) ? matrix.containers : producers
if (allProducers.length) await awaitProducerConsumption(context, allProducers)