fix(dropship): project sealed carton identities into overseas receiving
This commit is contained in:
@@ -4,11 +4,74 @@ import path from 'node:path'
|
||||
import test from 'node:test'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { expandOverseasCartonCandidates, run } from './phase4-overseas-pda.mjs'
|
||||
import { expandOverseasCartonCandidates, resolveCartonFixtures, run } from './phase4-overseas-pda.mjs'
|
||||
|
||||
const here = path.dirname(fileURLToPath(import.meta.url))
|
||||
const source = fs.readFileSync(path.join(here, 'phase4-overseas-pda.mjs'), 'utf8')
|
||||
|
||||
test('dropship original counted cartons must resolve exactly before any receiving or inventory checks', async () => {
|
||||
const inbounds = [{ inboundCode: 'REAL-INBOUND', destinationType: 'OVERSEAS', totalPackages: 2 }]
|
||||
const producer = { fulfillmentType: 'ONE_CLICK_DROPSHIP', inboundCode: 'REAL-INBOUND', destinationType: 'OVERSEAS',
|
||||
sealedCartonMarks: ['REAL-INBOUND#2-2', 'REAL-INBOUND#2-1'] }
|
||||
for (const fault of [null, 'missing-carton', 'wrong-carton', 'wrong-inbound', 'wrong-destination']) {
|
||||
const calls = []; const checks = []
|
||||
const context = {
|
||||
async requestOverseas(method, requestPath, body) {
|
||||
calls.push({ method, requestPath, body })
|
||||
const data = { cartonMark: body.cartonMark, inboundCode: 'REAL-INBOUND', destinationType: 'OVERSEAS' }
|
||||
if (fault === 'wrong-carton') data.cartonMark = 'ANOTHER-CARTON'
|
||||
if (fault === 'wrong-inbound') data.inboundCode = 'ANOTHER-INBOUND'
|
||||
if (fault === 'wrong-destination') data.destinationType = 'FBA'
|
||||
return { http: 200, body: { code: fault === 'missing-carton' ? 'A0404' : '200',
|
||||
message: 'Carton mark was not found', data }, requestId: 'request', traceId: 'trace' }
|
||||
},
|
||||
assert(module, name, response, passed) { checks.push({ name, passed }) },
|
||||
addStep(module, name, response, passed) { checks.push({ name, passed }) },
|
||||
addCoverageGap() {},
|
||||
}
|
||||
const result = await resolveCartonFixtures(context, 'token', inbounds, ['OLD-CANDIDATE#20-1'], producer)
|
||||
assert.ok(calls.every(call => call.method === 'POST' && call.requestPath.endsWith('/current/cartons/resolve')))
|
||||
assert.ok(calls.every(call => producer.sealedCartonMarks.includes(call.body.cartonMark)))
|
||||
if (fault) {
|
||||
assert.equal(result, null, fault)
|
||||
assert.ok(checks.some(check => !check.passed), fault)
|
||||
assert.ok(!checks.some(check => check.name.includes('排除未实装箱码候选')), fault)
|
||||
} else {
|
||||
assert.deepEqual(result.map(item => item.cartonMark), producer.sealedCartonMarks)
|
||||
assert.equal(calls.length, 2)
|
||||
assert.ok(checks.every(check => check.passed))
|
||||
}
|
||||
}
|
||||
for (const sealedCartonMarks of [undefined, [], ['REAL-INBOUND#2-1'], ['REAL-INBOUND#2-1', 'REAL-INBOUND#2-1']]) {
|
||||
const checks = []
|
||||
const result = await resolveCartonFixtures({ assert(m,n,r,passed) { checks.push(passed) },
|
||||
async requestOverseas() { assert.fail('incomplete physical fixture must not issue HTTP') } },
|
||||
'token', inbounds, producer.sealedCartonMarks, { ...producer, sealedCartonMarks })
|
||||
assert.equal(result, null)
|
||||
assert.deepEqual(checks, [false])
|
||||
}
|
||||
})
|
||||
|
||||
test('current loading event binds each pallet carton group to an explicit source detail', () => {
|
||||
const model = fs.readFileSync(path.join(here, '../../common-event-contract/src/main/java/com/baiyue/common/event/FirstLegLoadingPlanCompletedV2.java'), 'utf8')
|
||||
const producer = fs.readFileSync(path.join(here, '../../firstleg/src/main/java/com/baiyue/firstleg/service/LoadingCompletedOutboxService.java'), 'utf8')
|
||||
assert.match(model, /record SkuPackageSnapshot\(String sourceInboundDetailId, String skuCode/)
|
||||
assert.match(model, /sourceInboundDetailId == null \|\| sourceInboundDetailId\.isBlank\(\)/)
|
||||
assert.match(producer, /SkuPackageSnapshot\(detail\.detailId\(\)\.toString\(\), detail\.skuCode\(\)/)
|
||||
assert.match(producer, /SkuPackageSnapshot\(detail\.getSourceInboundDetailId\(\)\.toString\(\), detail\.getSkuCode\(\)/)
|
||||
const measurement = fs.readFileSync(path.join(here, 'inbound-measurement.mjs'), 'utf8')
|
||||
const loading = fs.readFileSync(path.join(here, 'phase3-loading.mjs'), 'utf8')
|
||||
const finalize = fs.readFileSync(path.join(here, 'phase3-loading-finalize.mjs'), 'utf8')
|
||||
assert.match(measurement, /sealedCartonMarks\.push\(resolved\.boxCode\)/)
|
||||
assert.match(loading, /phase3Loading\.cartonMarks = marks/)
|
||||
assert.match(finalize, /sealedCartonMarks: Array\.isArray\(fixture\.sealedCartonMarks\)/)
|
||||
const entry = fs.readFileSync(path.join(here, '../admin-test-env-acceptance.mjs'), 'utf8')
|
||||
assert.match(entry, /sealedCartonMarks: Array\.isArray\(fixture\.sealedCartonMarks\)/)
|
||||
assert.match(entry, /runPhase4ProducerVariant\('OVERSEAS-PRIMARY', 'OVERSEAS', 'ONE_CLICK_DROPSHIP', true\)/)
|
||||
assert.match(source, /resolveCartonFixtures\(context, token, current\.data\.inbounds, producerCartonMarks, preferredProducer\)/)
|
||||
assert.ok(source.indexOf('const cartonFixtures = await resolveCartonFixtures') < source.indexOf('const completed = await pda'))
|
||||
})
|
||||
|
||||
test('PDA module is injected, token-scoped, traceable, and contains no direct network or secret source', () => {
|
||||
assert.match(source, /export async function run\(context\)/)
|
||||
assert.match(source, /requestOverseas\(/)
|
||||
|
||||
Reference in New Issue
Block a user