完成单机TEST统一入口与可靠投递回归收尾
This commit is contained in:
@@ -48,8 +48,8 @@ async function merchantLogin(context, fixture) {
|
||||
const response = await context.request('POST', '/api/auth/login', { loginId: fixture.username, password: fixture.password }, '')
|
||||
const auth = success(response) ? response.body.data : null
|
||||
assert(context, '客户账号同时取得国内和海外短时Token', response,
|
||||
Boolean(auth?.accessToken) && Boolean(auth?.overseasAccessToken),
|
||||
`customerId=${fixture.tenantId}, domestic=${Boolean(auth?.accessToken)}, overseas=${Boolean(auth?.overseasAccessToken)}`)
|
||||
Boolean(auth?.accessToken) && Boolean(auth?.accessToken),
|
||||
`customerId=${fixture.tenantId}, domestic=${Boolean(auth?.accessToken)}, overseas=${Boolean(auth?.accessToken)}`)
|
||||
return auth
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ async function prepareWallet(context, customerId) {
|
||||
return success(recharge) ? { before: before.account, funded: recharge.body.data, rechargeAmount, creditLimit } : null
|
||||
}
|
||||
|
||||
async function procurementFlow(context, fixture, overseasToken) {
|
||||
async function procurementFlow(context, fixture, token) {
|
||||
const merchantPath = '/api/merchant/v1/last-leg/overseas-procurements'
|
||||
const payload = {
|
||||
customerName: fixture.tenantName, purchaseCategory: 'OFFICE_SUPPLIES', productName: `${context.marker} 钱包采购`,
|
||||
@@ -105,7 +105,7 @@ async function procurementFlow(context, fixture, overseasToken) {
|
||||
contactName: '全量验收联系人', contactPhone: '13800000002', remark: context.marker,
|
||||
idempotencyKey: `${context.marker}-wallet-procurement`.slice(0, 255),
|
||||
}
|
||||
const created = await context.requestOverseas('POST', merchantPath, payload, {}, overseasToken)
|
||||
const created = await context.request('POST', merchantPath, payload, token, {})
|
||||
const detail = created?.body?.data
|
||||
const orderNo = detail?.summary?.orderNo
|
||||
assert(context, '客户创建钱包采购单', created,
|
||||
@@ -117,7 +117,7 @@ async function procurementFlow(context, fixture, overseasToken) {
|
||||
`orderNo=${orderNo}, expectedPrefix=${fixture.expectedProcurementPrefix || 'custom-customer'}`)
|
||||
|
||||
const customerId = id(fixture.tenantId)
|
||||
const approved = await context.requestOverseas('POST', query(`${PROCUREMENT}/${encodeURIComponent(orderNo)}/review`, { customerId }), {
|
||||
const approved = await context.request('POST', query(`${PROCUREMENT}/${encodeURIComponent(orderNo)}/review`, { customerId }), {
|
||||
version: Number(detail.summary.version), decision: 'APPROVE',
|
||||
idempotencyKey: `${context.marker}-wallet-procurement-review`.slice(0, 255), remark: context.marker,
|
||||
})
|
||||
@@ -128,7 +128,7 @@ async function procurementFlow(context, fixture, overseasToken) {
|
||||
|
||||
const files = []
|
||||
for (const category of ['VOUCHER', 'RECEIPT']) {
|
||||
const uploaded = await context.requestOverseasMultipart('POST',
|
||||
const uploaded = await context.requestMultipart('POST',
|
||||
query(`${PROCUREMENT}/${encodeURIComponent(orderNo)}/files/${category}`, { customerId }),
|
||||
{ content: PNG, type: 'image/png', name: `${category.toLowerCase()}-${orderNo}.png` })
|
||||
assert(context, `采购单上传${category}文件`, uploaded,
|
||||
@@ -138,7 +138,7 @@ async function procurementFlow(context, fixture, overseasToken) {
|
||||
}
|
||||
if (files.length !== 2) return null
|
||||
|
||||
const fee = await context.requestOverseas('POST', query(`${PROCUREMENT}/${encodeURIComponent(orderNo)}/fees`, { customerId }), {
|
||||
const fee = await context.request('POST', query(`${PROCUREMENT}/${encodeURIComponent(orderNo)}/fees`, { customerId }), {
|
||||
feeItemCode: 'PROCUREMENT_SERVICE', feeItemName: '采购服务费', amount: 0.01,
|
||||
voucherFileId: id(files.find((item) => item.category === 'VOUCHER')?.fileId), remark: context.marker,
|
||||
})
|
||||
@@ -149,7 +149,7 @@ async function procurementFlow(context, fixture, overseasToken) {
|
||||
if (!success(fee) || !feeNo) return null
|
||||
|
||||
const detailPath = query(`${PROCUREMENT}/${encodeURIComponent(orderNo)}`, { customerId })
|
||||
const frozen = await poll(async () => context.requestOverseas('GET', detailPath),
|
||||
const frozen = await poll(async () => context.request('GET', detailPath),
|
||||
(response) => success(response) && response.body.data?.fees?.find((item) => item.feeNo === feeNo)?.walletStatus === 'FROZEN')
|
||||
const frozenFee = frozen.result?.body?.data?.fees?.find((item) => item.feeNo === feeNo)
|
||||
assert(context, '采购费用跨区冻结到账', frozen.result,
|
||||
@@ -157,13 +157,13 @@ async function procurementFlow(context, fixture, overseasToken) {
|
||||
if (frozenFee?.walletStatus !== 'FROZEN') return null
|
||||
|
||||
const current = frozen.result.body.data.summary
|
||||
const settledOrder = await context.requestOverseas('PATCH', detailPath, {
|
||||
const settledOrder = await context.request('PATCH', detailPath, {
|
||||
version: Number(current.version), inboundQuantity: Number(current.purchaseQuantity),
|
||||
})
|
||||
assert(context, '采购全量入库推进待出库并触发结算', settledOrder,
|
||||
success(settledOrder) && settledOrder.body.data?.summary?.status === 'PENDING_OUTBOUND',
|
||||
`status=${settledOrder.body?.data?.summary?.status || 'missing'}`)
|
||||
const settled = await poll(async () => context.requestOverseas('GET', detailPath),
|
||||
const settled = await poll(async () => context.request('GET', detailPath),
|
||||
(response) => success(response) && response.body.data?.fees?.find((item) => item.feeNo === feeNo)?.walletStatus === 'SETTLED')
|
||||
const settledFee = settled.result?.body?.data?.fees?.find((item) => item.feeNo === feeNo)
|
||||
assert(context, '采购费用跨区结算到账', settled.result,
|
||||
@@ -191,10 +191,9 @@ function relabelPayload(context, warehouseId, source, suffix, chargeAmount) {
|
||||
}
|
||||
}
|
||||
|
||||
async function relabelFlow(context, overseasToken, warehouseId, suffix, terminalStatus) {
|
||||
const candidatesResponse = await context.requestOverseas('GET', query(
|
||||
'/api/merchant/v1/last-leg/relabel-applications/inventory-candidates', { operationWarehouseId: warehouseId }),
|
||||
undefined, {}, overseasToken)
|
||||
async function relabelFlow(context, token, warehouseId, suffix, terminalStatus) {
|
||||
const candidatesResponse = await context.request('GET', query(
|
||||
'/api/merchant/v1/last-leg/relabel-applications/inventory-candidates', { operationWarehouseId: warehouseId }), undefined, token, {})
|
||||
const candidates = success(candidatesResponse) && Array.isArray(candidatesResponse.body?.data)
|
||||
? candidatesResponse.body.data : []
|
||||
const currentPda = context.createdResources?.phase4OverseasPda
|
||||
@@ -229,7 +228,7 @@ async function relabelFlow(context, overseasToken, warehouseId, suffix, terminal
|
||||
Boolean(source?.position), `warehouseId=${warehouseId}, candidates=${candidates.length}`)
|
||||
if (!source?.position) return null
|
||||
const payload = relabelPayload(context, warehouseId, source, suffix, 0.01)
|
||||
const created = await context.requestOverseas('POST', '/api/merchant/v1/last-leg/relabel-applications', payload, {}, overseasToken)
|
||||
const created = await context.request('POST', '/api/merchant/v1/last-leg/relabel-applications', payload, token, {})
|
||||
const relabelNo = created?.body?.data?.application?.relabelNo
|
||||
assert(context, `${suffix}换标单创建并携带收费金额`, created,
|
||||
success(created) && Boolean(relabelNo) && money(created.body.data?.application?.chargeAmount) === 0.01,
|
||||
@@ -237,7 +236,7 @@ async function relabelFlow(context, overseasToken, warehouseId, suffix, terminal
|
||||
if (!success(created) || !relabelNo) return null
|
||||
|
||||
const detailPath = `${RELABEL}/${encodeURIComponent(relabelNo)}`
|
||||
const frozen = await poll(async () => context.requestOverseas('GET', detailPath),
|
||||
const frozen = await poll(async () => context.request('GET', detailPath),
|
||||
(response) => success(response) && response.body.data?.application?.walletStatus === 'FROZEN')
|
||||
assert(context, `${suffix}换标费用跨区冻结到账`, frozen.result,
|
||||
frozen.result?.body?.data?.application?.walletStatus === 'FROZEN',
|
||||
@@ -245,32 +244,29 @@ async function relabelFlow(context, overseasToken, warehouseId, suffix, terminal
|
||||
if (frozen.result?.body?.data?.application?.walletStatus !== 'FROZEN') return null
|
||||
|
||||
const reviewStatus = terminalStatus === 'COMPLETED' ? 'PENDING_PROCESSING' : 'CANCELLED'
|
||||
const review = await context.requestOverseas('PUT', query(
|
||||
const review = await context.request('PUT', query(
|
||||
`/api/platform/v1/last-leg/orders/${encodeURIComponent(id(created.body.data.application.lastlegOrderId))}/relabel-review`,
|
||||
{ customerId: id(context.context.merchantQualificationFixture.tenantId) }),
|
||||
{ status: reviewStatus, remark: context.marker })
|
||||
{ customerId: id(context.context.merchantQualificationFixture.tenantId) }), { status: reviewStatus, remark: context.marker })
|
||||
assert(context, `${suffix}尾程订单审核直接贴标申请`, review,
|
||||
success(review) && review.body.data?.application?.status === reviewStatus)
|
||||
if (!success(review)) return null
|
||||
|
||||
if (terminalStatus === 'COMPLETED') {
|
||||
const processing = await context.requestOverseas('PUT', `${detailPath}/status`, { status: 'PROCESSING', remark: context.marker })
|
||||
const processing = await context.request('PUT', `${detailPath}/status`, { status: 'PROCESSING', remark: context.marker })
|
||||
assert(context, '换标单冻结后才允许进入处理中', processing,
|
||||
success(processing) && processing.body.data?.application?.status === 'PROCESSING')
|
||||
const confirmPending = await context.requestOverseas('PUT', `${detailPath}/status`,
|
||||
{ status: 'CUSTOMER_CONFIRM_PENDING', remark: context.marker })
|
||||
const confirmPending = await context.request('PUT', `${detailPath}/status`, { status: 'CUSTOMER_CONFIRM_PENDING', remark: context.marker })
|
||||
assert(context, '换标处理完成后进入客户确认', confirmPending,
|
||||
success(confirmPending) && confirmPending.body.data?.application?.status === 'CUSTOMER_CONFIRM_PENDING')
|
||||
const readyForOutbound = await context.requestOverseas('PUT', `${detailPath}/status`,
|
||||
{ status: 'READY_FOR_OUTBOUND', remark: context.marker })
|
||||
const readyForOutbound = await context.request('PUT', `${detailPath}/status`, { status: 'READY_FOR_OUTBOUND', remark: context.marker })
|
||||
assert(context, '换标客户确认后进入待出库', readyForOutbound,
|
||||
success(readyForOutbound) && readyForOutbound.body.data?.application?.status === 'READY_FOR_OUTBOUND')
|
||||
}
|
||||
const terminal = terminalStatus === 'CANCELLED' ? review : await context.requestOverseas('PUT', `${detailPath}/status`, { status: terminalStatus, remark: context.marker })
|
||||
const terminal = terminalStatus === 'CANCELLED' ? review : await context.request('PUT', `${detailPath}/status`, { status: terminalStatus, remark: context.marker })
|
||||
assert(context, `${suffix}换标单进入${terminalStatus}`, terminal,
|
||||
success(terminal) && terminal.body.data?.application?.status === terminalStatus)
|
||||
const walletTerminal = terminalStatus === 'COMPLETED' ? 'SETTLED' : 'RELEASED'
|
||||
const wallet = await poll(async () => context.requestOverseas('GET', detailPath),
|
||||
const wallet = await poll(async () => context.request('GET', detailPath),
|
||||
(response) => success(response) && response.body.data?.application?.walletStatus === walletTerminal)
|
||||
assert(context, `${suffix}换标费用跨区${walletTerminal}`, wallet.result,
|
||||
wallet.result?.body?.data?.application?.walletStatus === walletTerminal,
|
||||
@@ -308,14 +304,13 @@ async function verifyPalletSummaries(context, warehouseId) {
|
||||
success(domestic) && summaryValid(d, ['totalCount', 'idleCount', 'occupiedCount'])
|
||||
&& Number(d.totalCount) === Number(d.idleCount) + Number(d.occupiedCount),
|
||||
`total=${d?.totalCount}, idle=${d?.idleCount}, occupied=${d?.occupiedCount}`)
|
||||
const overseas = await context.requestOverseas('GET', '/api/platform/v1/warehouse-admin/pallets/summary?page=1&size=20')
|
||||
const overseas = await context.request('GET', '/api/platform/v1/warehouse-admin/pallets/summary?page=1&size=20')
|
||||
const o = overseas?.body?.data
|
||||
assert(context, '海外托盘汇总含闲置、占用和报废数量', overseas,
|
||||
success(overseas) && summaryValid(o, ['totalCount', 'idleCount', 'occupiedCount', 'scrappedCount'])
|
||||
&& Number(o.totalCount) === Number(o.idleCount) + Number(o.occupiedCount) + Number(o.scrappedCount),
|
||||
`total=${o?.totalCount}, idle=${o?.idleCount}, occupied=${o?.occupiedCount}, scrapped=${o?.scrappedCount}`)
|
||||
const warehouse = await context.requestOverseas('GET',
|
||||
`/api/platform/v1/warehouse-admin/${encodeURIComponent(warehouseId)}/pallets/summary?page=1&size=20`)
|
||||
const warehouse = await context.request('GET', `/api/platform/v1/overseas-warehouse-resources/${encodeURIComponent(warehouseId)}/pallets/summary?page=1&size=20`)
|
||||
assert(context, '海外仓级托盘汇总可用', warehouse,
|
||||
success(warehouse) && summaryValid(warehouse.body.data, ['totalCount', 'idleCount', 'occupiedCount', 'scrappedCount']))
|
||||
}
|
||||
@@ -324,7 +319,7 @@ async function verifyDestuffCosts(context, completedFacts) {
|
||||
const evidence = []
|
||||
for (const fact of completedFacts) {
|
||||
const businessNo = `DESTUFF-${fact.containerBookingId}`
|
||||
const lastleg = await poll(async () => context.requestOverseas('GET', query('/api/platform/v1/last-leg/finance-fee-sources', {
|
||||
const lastleg = await poll(async () => context.request('GET', query('/api/platform/v1/last-leg/finance-fee-sources', {
|
||||
businessType: 'OVERSEAS_CONTAINER', businessNo,
|
||||
})), (response) => success(response) && rows(response.body.data).length > 0, 75)
|
||||
const sources = success(lastleg.result) ? rows(lastleg.result.body.data) : []
|
||||
@@ -363,9 +358,9 @@ export async function run(context) {
|
||||
|
||||
const auth = await merchantLogin(context, fixture)
|
||||
const wallet = auth ? await prepareWallet(context, id(fixture.tenantId)) : null
|
||||
const procurement = wallet ? await procurementFlow(context, fixture, auth.overseasAccessToken) : null
|
||||
const settledRelabel = procurement ? await relabelFlow(context, auth.overseasAccessToken, warehouseId, 'SETTLE', 'COMPLETED') : null
|
||||
const releasedRelabel = settledRelabel ? await relabelFlow(context, auth.overseasAccessToken, warehouseId, 'RELEASE', 'CANCELLED') : null
|
||||
const procurement = wallet ? await procurementFlow(context, fixture, auth.accessToken) : null
|
||||
const settledRelabel = procurement ? await relabelFlow(context, auth.accessToken, warehouseId, 'SETTLE', 'COMPLETED') : null
|
||||
const releasedRelabel = settledRelabel ? await relabelFlow(context, auth.accessToken, warehouseId, 'RELEASE', 'CANCELLED') : null
|
||||
const relabels = [settledRelabel, releasedRelabel].filter(Boolean)
|
||||
const finalAccount = procurement && relabels.length === 2
|
||||
? await verifyClientWallet(context, auth.accessToken, fixture, wallet, procurement, relabels) : null
|
||||
|
||||
Reference in New Issue
Block a user