test: automate overseas wallet and pallet cost closure
This commit is contained in:
@@ -40,6 +40,36 @@ async function request(context, token, method, name, path, body = undefined) {
|
||||
return { response, data: success(response) ? response.body?.data : null }
|
||||
}
|
||||
|
||||
async function poll(action, predicate, attempts = 60) {
|
||||
let result = null
|
||||
for (let index = 0; index < attempts; index += 1) {
|
||||
result = await action()
|
||||
if (predicate(result)) return { result, attempts: index + 1 }
|
||||
if (index + 1 < attempts) await new Promise((resolve) => setTimeout(resolve, 1_000))
|
||||
}
|
||||
return { result, attempts }
|
||||
}
|
||||
|
||||
async function fundRelabelWallet(context, customerId) {
|
||||
const accountResponse = await context.request('GET',
|
||||
`/api/platform/finance/v1/accounts?page=1&pageSize=20&customerId=${encodeURIComponent(customerId)}`)
|
||||
const account = success(accountResponse)
|
||||
? records(accountResponse.body?.data).find((item) => id(item?.customerId) === customerId) : null
|
||||
context.addStep(MODULE, 'P5读取本轮客户钱包版本', accountResponse,
|
||||
Boolean(account) && Number.isInteger(Number(account.accountVersion)), trace(accountResponse), OPTIONS)
|
||||
if (!account) return false
|
||||
const recharge = await context.request('POST',
|
||||
`/api/platform/finance/v1/accounts/${encodeURIComponent(customerId)}/adjustments`, {
|
||||
type: 'RECHARGE', amount: 1, occurredDate: new Date().toISOString().slice(0, 10),
|
||||
paymentMethod: 'BANK_TRANSFER', referenceNo: `${context.marker}-P5`, remark: context.marker,
|
||||
expectedAccountVersion: Number(account.accountVersion),
|
||||
}, context.token, { 'Idempotency-Key': key(context, 'RELABEL-WALLET-FUND') })
|
||||
context.addStep(MODULE, 'P5为收费换标准备本轮隔离实际余额', recharge,
|
||||
success(recharge) && Number(recharge.body?.data?.actualBalanceAfter) >= 1,
|
||||
`actualBalanceAfter=${recharge.body?.data?.actualBalanceAfter ?? 'missing'}; ${trace(recharge)}`, OPTIONS)
|
||||
return success(recharge)
|
||||
}
|
||||
|
||||
async function expectConflict(context, token, method, name, path, body) {
|
||||
const response = await context.requestOverseas(method, path, body, {}, token)
|
||||
context.addStep(MODULE, name, response, conflict(response), trace(response), OPTIONS)
|
||||
@@ -292,13 +322,14 @@ async function verifyRelabel(context, token, fixture) {
|
||||
blocker(context, 'P5本轮库存换标申请', '缺少本轮完成库存的客户、SKU或海外仓事实')
|
||||
return false
|
||||
}
|
||||
if (!await fundRelabelWallet(context, customerId)) return false
|
||||
const relabelBase = '/api/platform/v1/last-leg/relabel-applications'
|
||||
const pdaBase = '/api/pda/v1/last-leg/relabel-tasks'
|
||||
const newSku = `${inventory.skuCode}-NEW-${String(context.marker).slice(-8)}`.slice(0, 128)
|
||||
const createBody = {
|
||||
customerOrderNo: String(customerOrderNo).slice(0, 128), overseasWarehouseId: id(fixture.overseasWarehouseId),
|
||||
labelDeadline: new Date(Date.now() + 7 * 86400000).toISOString().slice(0, 19),
|
||||
contactName: 'PDA换标验收', contactPhone: '13800000006', remark: context.marker,
|
||||
contactName: 'PDA换标验收', contactPhone: '13800000006', chargeAmount: 0.01, remark: context.marker,
|
||||
idempotencyKey: key(context, 'RELABEL-CREATE'),
|
||||
items: [{ skuCode: inventory.skuCode, productNameZh: inventory.productName || '本轮库存商品',
|
||||
totalPackageCount: 3, notifiedPackageCount: 3, shipmentNo: `SHIP-${context.marker}`.slice(0, 128),
|
||||
@@ -316,6 +347,12 @@ async function verifyRelabel(context, token, fixture) {
|
||||
blocker(context, 'P5真实换标申请', '平台正式换标创建接口未返回申请单号', createdResponse)
|
||||
return false
|
||||
}
|
||||
const funded = await poll(async () => context.requestOverseas('GET', `${relabelBase}/${encodeURIComponent(relabelNo)}`),
|
||||
(response) => success(response) && response.body?.data?.application?.walletStatus === 'FROZEN')
|
||||
context.addStep(MODULE, 'P5换标费用冻结后开放PDA作业', funded.result,
|
||||
funded.result?.body?.data?.application?.walletStatus === 'FROZEN',
|
||||
`pollRequests=${funded.attempts}, walletStatus=${funded.result?.body?.data?.application?.walletStatus || 'missing'}; ${trace(funded.result)}`, OPTIONS)
|
||||
if (funded.result?.body?.data?.application?.walletStatus !== 'FROZEN') return false
|
||||
const candidates = await request(context, token, 'GET', 'P5读取当前仓换标候选', `${pdaBase}/candidates`)
|
||||
context.assert(MODULE, 'P5候选包含本轮真实申请', candidates.response,
|
||||
Array.isArray(candidates.data) && candidates.data.some((item) => id(item?.relabelNo) === relabelNo),
|
||||
@@ -404,7 +441,12 @@ async function verifyRelabel(context, token, fixture) {
|
||||
context.assert(MODULE, 'P5最终任务和申请均COMPLETED', approveReplay.response,
|
||||
approved.data?.taskStatus === 'COMPLETED' && approved.data?.applicationStatus === 'COMPLETED'
|
||||
&& approveReplay.data?.taskStatus === 'COMPLETED', trace(approveReplay.response), OPTIONS)
|
||||
return success(approved.response)
|
||||
const settled = await poll(async () => context.requestOverseas('GET', `${relabelBase}/${encodeURIComponent(relabelNo)}`),
|
||||
(response) => success(response) && response.body?.data?.application?.walletStatus === 'SETTLED')
|
||||
context.addStep(MODULE, 'P5换标完成后钱包结算收敛', settled.result,
|
||||
settled.result?.body?.data?.application?.walletStatus === 'SETTLED',
|
||||
`pollRequests=${settled.attempts}, walletStatus=${settled.result?.body?.data?.application?.walletStatus || 'missing'}; ${trace(settled.result)}`, OPTIONS)
|
||||
return success(approved.response) && settled.result?.body?.data?.application?.walletStatus === 'SETTLED'
|
||||
}
|
||||
|
||||
export async function run(context) {
|
||||
|
||||
Reference in New Issue
Block a user