From d5d3364275d57c62ff8ab6194cc3056aa4e09044 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Thu, 24 Sep 2026 00:04:03 +0800 Subject: [PATCH] test: stabilize admin full acceptance flows --- scripts/admin-test-env-modules/phase4-carrier-nodes.mjs | 7 ++++++- .../phase4-overseas-return-receipt.mjs | 6 +++++- .../phase4-overseas-wallet-and-pallet-cost.mjs | 7 +++++++ .../admin-test-env-modules/return-boundary-scenarios.mjs | 9 ++++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/scripts/admin-test-env-modules/phase4-carrier-nodes.mjs b/scripts/admin-test-env-modules/phase4-carrier-nodes.mjs index deeb6b306..ae5d54772 100644 --- a/scripts/admin-test-env-modules/phase4-carrier-nodes.mjs +++ b/scripts/admin-test-env-modules/phase4-carrier-nodes.mjs @@ -342,8 +342,13 @@ export async function run(context) { const finalTask = detail.query.query const actualNodes = new Set(detail.nodes.filter((item) => item.actualAt != null).map((item) => item.standardNode)) + // Terminal drayage records actual pickup as the unload completion time on the + // aggregate. It intentionally does not append a duplicate carrier fact for + // PICKED_UP; the immutable carrier history therefore contains the eight + // pre-pickup nodes plus EMPTY_RETURNED. + const carrierNodesWithoutInferredPickup = STANDARD_NODES.filter((node) => node !== 'PICKED_UP') context.assert(MODULE, '拖车业务回写后覆盖十标准实际节点且EMPTY_RETURNED停止', detailResponse, - STANDARD_NODES.every((node) => actualNodes.has(node)) && finalTask.status === 'STOPPED' + carrierNodesWithoutInferredPickup.every((node) => actualNodes.has(node)) && finalTask.status === 'STOPPED' && finalTask.latestActualNode === 'EMPTY_RETURNED' && finalTask.stopReason === '已还柜' && id(finalTask.containerBookingId) === id(drayage.containerBookingId), `actualNodes=${[...actualNodes].join(',')}, status=${finalTask.status}`, OPTIONS) diff --git a/scripts/admin-test-env-modules/phase4-overseas-return-receipt.mjs b/scripts/admin-test-env-modules/phase4-overseas-return-receipt.mjs index 4507940a6..a523ce5f3 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-return-receipt.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-return-receipt.mjs @@ -55,7 +55,11 @@ function add(context, name, response, passed, evidence = '') { } async function overseas(context, token, method, name, path, body = undefined) { - const response = await context.requestOverseas(method, path, body, {}, token) + let response = await context.requestOverseas(method, path, body, {}, token) + for (let attempt = 1; attempt < 3 && response?.http === 0; attempt += 1) { + await new Promise((resolve) => setTimeout(resolve, 250 * attempt)) + response = await context.requestOverseas(method, path, body, {}, token) + } add(context, name, response, success(response)) return { response, data: success(response) ? response.body?.data : null } } diff --git a/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs b/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs index bbb213f2f..926bfa7f0 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-wallet-and-pallet-cost.mjs @@ -197,9 +197,16 @@ async function relabelFlow(context, overseasToken, warehouseId, suffix, terminal undefined, {}, overseasToken) const candidates = success(candidatesResponse) && Array.isArray(candidatesResponse.body?.data) ? candidatesResponse.body.data : [] + const currentPda = context.createdResources?.phase4OverseasPda + const protectedPalletIds = new Set([ + ...(Array.isArray(currentPda?.palletIds) ? currentPda.palletIds : []), + ...Object.values(currentPda?.generatedPalletsByInbound || {}) + .flatMap((items) => Array.isArray(items) ? items.map((item) => id(item?.palletId)) : []), + ].filter(Boolean)) const source = candidates.find((candidate) => id(candidate.inboundOrderId) && id(candidate.inventoryBalanceId) && id(candidate.destinationFbaWarehouseCode) + && !candidate.positions?.some((position) => protectedPalletIds.has(id(position?.palletId))) && candidate.positions?.some((position) => id(position.positionId) && Number(position.availablePackages) > 0)) if (source) source.position = source.positions.find((position) => id(position.positionId) && Number(position.availablePackages) > 0) diff --git a/scripts/admin-test-env-modules/return-boundary-scenarios.mjs b/scripts/admin-test-env-modules/return-boundary-scenarios.mjs index 2a09c6e46..1654dfa06 100644 --- a/scripts/admin-test-env-modules/return-boundary-scenarios.mjs +++ b/scripts/admin-test-env-modules/return-boundary-scenarios.mjs @@ -60,7 +60,14 @@ export async function runReturnBoundaries(context, { merchantToken, warehouse, p if (!passed) failures += 1 context.assert(MODULE, name, response, Boolean(passed), evidence, OPTIONS) } - const request = (token, method, path, body) => context.requestOverseas(method, path, body, {}, token) + async function request(token, method, path, body) { + let response = await context.requestOverseas(method, path, body, {}, token) + for (let attempt = 1; attempt < 3 && response?.http === 0; attempt += 1) { + await new Promise((resolve) => setTimeout(resolve, 250 * attempt)) + response = await context.requestOverseas(method, path, body, {}, token) + } + return response + } async function good(token, method, name, path, body) { const response = await request(token, method, path, body) check(name, response, ok(response))