Test #1

Merged
admin merged 1726 commits from test into main 2026-09-17 11:52:45 +08:00
5 changed files with 37 additions and 20 deletions
Showing only changes of commit 2abbb3cc8f - Show all commits
+5 -9
View File
@@ -1470,7 +1470,7 @@ export class AcceptanceRun {
const variantMarker = `${matrixMarker}-P4-${label}`
const contextKeys = ['orderDestinationType', 'orderFulfillmentType', 'phase4ProducerMatrixMarker']
const createdKeys = [
'phase3Loading', 'phase3LoadingCompletedProducer', 'phase3ContainerDocuments', 'orchestrationFixtures', 'inboundFees', 'oceanBooking',
'phase3Loading', 'phase3LoadingCompletedProducer', 'phase3ContainerDocuments', 'orchestrationFixtures', 'oceanBooking',
'phase3CustomsSupplier', 'phase3Customs', 'serviceCenterFlow', 'portSchedule',
'phase3OutboundDispatch', 'phase3CarrierScheduleQuery', 'phase4CarrierPickupReady',
]
@@ -1496,14 +1496,10 @@ export class AcceptanceRun {
// become impossible when the bounded isolation guard refuses bulk location mutations.
restoreFixture = await this.preparePhase3LoadingFixture('', false)
if (fulfillmentType === 'ONE_CLICK_DROPSHIP') {
const measuredFixture = this.createdResources.inboundMeasurement
this.createdResources.inboundMeasurement = this.createdResources.orchestrationFixtures?.phase3Loading
try {
const inboundFees = await import(new URL('./admin-test-env-modules/inbound-fees.mjs', import.meta.url))
await this.executeModule(`inbound-fees-phase4-${label}`, () => inboundFees.run(this))
} finally {
this.createdResources.inboundMeasurement = measuredFixture
}
const inboundFees = await import(new URL('./admin-test-env-modules/inbound-fees.mjs', import.meta.url))
await inboundFees.ensureInitialCalculated(this,
this.createdResources.orchestrationFixtures?.phase3Loading,
{ scenario: `phase4-${label}-initial-fee`, deploymentBlocker: true })
}
const loading = await import(new URL('./admin-test-env-modules/phase3-loading.mjs', import.meta.url))
await this.executeModule(`phase3-loading-phase4-${label}`, () => loading.run(this))
@@ -24,3 +24,13 @@ test('inbound fee lifecycle covers frozen source, version, publication and WAIT_
assert.match(source, /对客合计仅含已发布头程与已审核其他应收且其他应付单列/)
assert.doesNotMatch(source, /settlementIncluded|是否结算|参与结算/)
})
test('initial fee preparation is reusable without confirming or publishing the fee', async () => {
const source = await readFile(moduleFile, 'utf8')
assert.match(source, /export async function ensureInitialCalculated/)
const helper = source.slice(source.indexOf('export async function ensureInitialCalculated'), source.indexOf('export async function run'))
assert.match(helper, /\/fees\/latest/)
assert.match(helper, /\/fees\/calculate/)
assert.match(helper, /feeStatus === 'CALCULATED'/)
assert.doesNotMatch(helper, /\/fees\/confirm|\/fees\/send/)
})
@@ -25,15 +25,14 @@ async function listDetails(context, tenantId, inboundId, name) {
return { response, rows: Array.isArray(rows) ? rows : [] }
}
export async function run(context) {
const start = context.steps.length
const fixture = context.createdResources.inboundMeasurement
export async function ensureInitialCalculated(context, fixture,
options = { scenario: 'inbound-fee-initial-calculated', deploymentBlocker: true }) {
const tenantId = id(fixture?.tenantId)
const inboundId = id(fixture?.inboundId)
context.assert(MODULE, '复用本轮审核通过且进入 WAIT_SPLIT 的入库单', null,
Boolean(tenantId && inboundId && fixture?.finalStatus === 'APPROVED' && fixture?.processStatus === 'WAIT_SPLIT'),
`tenantId=${tenantId || 'missing'}, inboundId=${inboundId || 'missing'}, measurement=${fixture?.finalStatus || 'missing'}, process=${fixture?.processStatus || 'missing'}`, OPTIONS)
if (!tenantId || !inboundId) { finish(context, start); return }
`tenantId=${tenantId || 'missing'}, inboundId=${inboundId || 'missing'}, measurement=${fixture?.finalStatus || 'missing'}, process=${fixture?.processStatus || 'missing'}`, options)
if (!tenantId || !inboundId) return null
const latestPath = `/api/platform/v1/inbounds/${encodeURIComponent(inboundId)}/fees/latest?tenantId=${encodeURIComponent(tenantId)}`
let initialResponse = await context.request('GET', latestPath)
@@ -42,12 +41,22 @@ export async function run(context) {
`/api/platform/v1/inbounds/${encodeURIComponent(inboundId)}/fees/calculate?tenantId=${encodeURIComponent(tenantId)}`,
undefined, undefined, requestHeaders(`${context.marker}-inbound-fee-initial-calculate`))
}
const initial = context.apiSuccess(MODULE, '读取或补齐审核后初始费用', initialResponse, '', OPTIONS)
const initial = context.apiSuccess(MODULE, '读取或补齐审核后初始费用', initialResponse, '', options)
context.assert(MODULE, '初始费用保持 WAIT_SPLIT 且尚未发布', initialResponse,
initial?.feeStatus === 'CALCULATED' && initial?.nextProcessStatus === 'WAIT_SPLIT'
&& Number(initial?.feeVersion) >= 1 && money(initial?.totalAmount) >= 0,
`feeId=${id(initial?.feeId) || 'missing'}, version=${initial?.feeVersion ?? 'missing'}, status=${initial?.feeStatus || 'missing'}, process=${initial?.nextProcessStatus || 'missing'}`, OPTIONS)
if (!initial?.feeId || initial?.feeStatus !== 'CALCULATED') { finish(context, start); return }
`feeId=${id(initial?.feeId) || 'missing'}, version=${initial?.feeVersion ?? 'missing'}, status=${initial?.feeStatus || 'missing'}, process=${initial?.nextProcessStatus || 'missing'}`, options)
return initial?.feeId && initial?.feeStatus === 'CALCULATED'
? { initial, initialResponse, tenantId, inboundId }
: null
}
export async function run(context) {
const start = context.steps.length
const fixture = context.createdResources.inboundMeasurement
const prepared = await ensureInitialCalculated(context, fixture, OPTIONS)
if (!prepared) { finish(context, start); return }
const { initial, initialResponse, tenantId, inboundId } = prepared
const initialDetails = await listDetails(context, tenantId, inboundId, '查询初始费用派生明细')
const initialDerived = initialDetails.rows.find((row) => row.sourceType === 'FBA_PRICING'
@@ -85,8 +85,9 @@ test('measurement and loading pass destination identity into the LOADED producer
assert.match(entry, /runPhase4ProducerVariant\('DROPSHIP-PRIMARY', 'FBA', 'ONE_CLICK_DROPSHIP', true\)/)
assert.match(entry, /orderFulfillmentType/)
assert.match(entry, /fulfillmentType: fixtureOrder\.fulfillmentType \|\| 'STANDARD'/)
assert.match(entry, /inbound-fees-phase4-/)
assert.match(entry, /createdResources\.inboundMeasurement = this\.createdResources\.orchestrationFixtures\?\.phase3Loading/)
assert.match(entry, /inboundFees\.ensureInitialCalculated\(this,/)
assert.match(entry, /this\.createdResources\.orchestrationFixtures\?\.phase3Loading/)
assert.doesNotMatch(entry, /inbound-fees-phase4-|createdResources\.inboundMeasurement = this\.createdResources\.orchestrationFixtures/)
assert.match(entry, /skuCodes: Array\.isArray\(fixtureOrder\.skuCodes\) \? fixtureOrder\.skuCodes : \[\]/)
assert.match(entry, /skuLines: Array\.isArray\(fixtureOrder\.skuLines\) \? fixtureOrder\.skuLines : \[\]/)
const pda = read('phase4-overseas-pda.mjs')
@@ -163,8 +163,9 @@ test('PDA entry expands the real phase-three producer chain and builds an FBA/OV
assert.match(source, /runPhase4ProducerVariant\('SECONDARY', 'FBA', 'STANDARD', false\)/)
assert.match(source, /runUntilPickupReady\(this\)/)
const variant = source.slice(source.indexOf('async runPhase4ProducerVariant'), source.indexOf('async ensurePhase4PdaProducerMatrix'))
assert.ok(variant.indexOf('inbound-fees-phase4-') < variant.indexOf('phase3-loading-phase4-'))
assert.ok(variant.indexOf('ensureInitialCalculated') < variant.indexOf('phase3-loading-phase4-'))
assert.match(variant, /fulfillmentType === 'ONE_CLICK_DROPSHIP'/)
assert.doesNotMatch(variant, /inboundFees\.run\(this\)/)
assert.ok(variant.indexOf('phase3-outbound-dispatch-phase4-') < variant.indexOf('phase3-container-documents-phase4-'))
assert.ok(variant.indexOf('phase3-container-documents-phase4-') < variant.indexOf('phase3-carrier-schedule-queries-phase4-'))
assert.match(source, /\['phase3-container-documents', \['phase3-outbound-dispatch'\]\]/)