test: harden admin acceptance fixtures and transport retries
This commit is contained in:
@@ -537,28 +537,36 @@ function findIsolatedInbound(context) {
|
||||
}
|
||||
|
||||
async function multipartRequest(context, path, data) {
|
||||
const form = new FormData()
|
||||
form.append('data', new Blob([JSON.stringify(data)], { type: 'application/json' }))
|
||||
form.append('image', new Blob([WEIGHT_IMAGE], { type: 'image/png' }), 'carton-evidence.png')
|
||||
try {
|
||||
const response = await fetch(`${context.options.gateway}${path}`, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/json', Authorization: `Bearer ${context.token}` },
|
||||
body: form,
|
||||
signal: AbortSignal.timeout(60_000),
|
||||
})
|
||||
const content = await response.text()
|
||||
let body = null
|
||||
try { body = content ? JSON.parse(content) : null } catch { /* Preserve only a bounded error string. */ }
|
||||
return {
|
||||
method: 'POST', path, http: response.status, body,
|
||||
raw: body === null ? content.slice(0, 500) : null,
|
||||
requestId: body?.requestId || response.headers.get('x-request-id'),
|
||||
traceId: body?.traceId || response.headers.get('x-trace-id'),
|
||||
let lastResponse = null
|
||||
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
||||
const form = new FormData()
|
||||
form.append('data', new Blob([JSON.stringify(data)], { type: 'application/json' }))
|
||||
form.append('image', new Blob([WEIGHT_IMAGE], { type: 'image/png' }), 'carton-evidence.png')
|
||||
try {
|
||||
const response = await fetch(`${context.options.gateway}${path}`, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/json', Authorization: `Bearer ${context.token}` },
|
||||
body: form,
|
||||
signal: AbortSignal.timeout(60_000),
|
||||
})
|
||||
const content = await response.text()
|
||||
let body = null
|
||||
try { body = content ? JSON.parse(content) : null } catch { /* Preserve only a bounded error string. */ }
|
||||
lastResponse = {
|
||||
method: 'POST', path, http: response.status, body,
|
||||
raw: body === null ? content.slice(0, 500) : null,
|
||||
requestId: body?.requestId || response.headers.get('x-request-id'),
|
||||
traceId: body?.traceId || response.headers.get('x-trace-id'),
|
||||
}
|
||||
if (lastResponse.http !== 0 || attempt === 3) return lastResponse
|
||||
} catch (error) {
|
||||
lastResponse = { method: 'POST', path, http: 0, body: null,
|
||||
raw: error instanceof Error ? error.message : String(error), requestId: null, traceId: null }
|
||||
if (attempt === 3) return lastResponse
|
||||
}
|
||||
} catch (error) {
|
||||
return { method: 'POST', path, http: 0, body: null, raw: error instanceof Error ? error.message : String(error), requestId: null, traceId: null }
|
||||
await new Promise((resolve) => setTimeout(resolve, 400 * attempt))
|
||||
}
|
||||
return lastResponse
|
||||
}
|
||||
|
||||
async function requestWithHeaders(context, method, path, body, extraHeaders) {
|
||||
|
||||
@@ -753,7 +753,14 @@ export async function run(context) {
|
||||
}
|
||||
const fixturesByAuxiliaryCapacity = [...handoff.completedFixtures]
|
||||
.sort((left, right) => (right?.auxiliaryPallets?.length || 0) - (left?.auxiliaryPallets?.length || 0))
|
||||
// P4/P5 deliberately consumes and rearranges one multi-carton source. Keep the
|
||||
// ABE8 producer untouched when the matrix contains both destinations so the
|
||||
// following dispatch module can still observe RECEIVED candidates for ABE4+ABE8.
|
||||
const fixture = fixturesByAuxiliaryCapacity.find((item) => item?.destinationType === 'FBA'
|
||||
&& item?.fbaWarehouseCode === 'ABE4'
|
||||
&& (item?.auxiliaryPallets?.length || 0) > 0 && Array.isArray(item?.inventory)
|
||||
&& item.inventory.reduce((sum, line) => sum + Number(line?.availablePackages || 0), 0) > 3)
|
||||
|| fixturesByAuxiliaryCapacity.find((item) => item?.destinationType === 'FBA'
|
||||
&& (item?.auxiliaryPallets?.length || 0) > 0 && Array.isArray(item?.inventory)
|
||||
&& item.inventory.reduce((sum, line) => sum + Number(line?.availablePackages || 0), 0) > 3)
|
||||
|| fixturesByAuxiliaryCapacity.find((item) => item?.destinationType === 'OVERSEAS'
|
||||
|
||||
@@ -264,10 +264,19 @@ export async function run(context) {
|
||||
...firstBody, trackingNo: `TRACK-${suffix}-CHANGED`,
|
||||
}, {}, picker.token))
|
||||
|
||||
await reject('超收被拒绝且不得生成费用批次', conflict, () => context.requestOverseas('POST', `${PDA_RECEIPTS}/confirm`, {
|
||||
returnNo, startedBy: 'SKU', palletCode: cartonA, items: [{ skuCode: skuA, receivedQuantity: 2 }],
|
||||
idempotencyKey: key(context, 'OVER-RECEIPT'),
|
||||
}, {}, picker.token))
|
||||
await reject('超收被拒绝且不得生成费用批次', conflict, async () => {
|
||||
const body = {
|
||||
returnNo, startedBy: 'SKU', palletCode: cartonA, items: [{ skuCode: skuA, receivedQuantity: 2 }],
|
||||
idempotencyKey: key(context, 'OVER-RECEIPT'),
|
||||
}
|
||||
let response = null
|
||||
for (let attempt = 1; attempt <= 3; attempt += 1) {
|
||||
response = await context.requestOverseas('POST', `${PDA_RECEIPTS}/confirm`, body, {}, picker.token)
|
||||
if (response?.http !== 0 || attempt === 3) break
|
||||
await new Promise((resolve) => setTimeout(resolve, 400 * attempt))
|
||||
}
|
||||
return response
|
||||
})
|
||||
|
||||
for (const [name, changes, expected] of [
|
||||
['零实收数量', { items: [{ skuCode: skuA, receivedQuantity: 0 }] }, validationFailure],
|
||||
|
||||
Reference in New Issue
Block a user