优化
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
import { run } from './phase4-overseas-master-data.mjs'
|
||||
|
||||
const source = readFileSync(new URL('./phase4-overseas-master-data.mjs', import.meta.url), 'utf8')
|
||||
const DOMESTIC_BASE = '/api/platform/v1/warehouse-admin'
|
||||
const OVERSEAS_BASE = '/api/platform/v1/last-leg/master-data'
|
||||
const ok = (data) => ({ http: 200, body: { code: '200', message: 'success', data }, requestId: 'req-p4', traceId: 'trace-p4' })
|
||||
const conflict = () => ({ http: 200, body: { code: 'A0409', message: 'record version conflict', data: null }, requestId: 'req-conflict' })
|
||||
|
||||
function detailQuote(state) {
|
||||
return {
|
||||
summary: { ...state.summary },
|
||||
warehouseFees: state.warehouseFees.map((item) => ({ ...item })),
|
||||
transitPrices: state.transitPrices.map((item) => ({ ...item })),
|
||||
createdBy: 'admin', createdAt: '2026-08-21T00:00:00',
|
||||
}
|
||||
}
|
||||
|
||||
function vehicleWire(state) {
|
||||
return { ...state.vehicle, mileageKm: String(state.vehicle.mileageKm), recordVersion: String(state.vehicle.recordVersion) }
|
||||
}
|
||||
|
||||
function fakeContext() {
|
||||
const calls = []
|
||||
const coverageGaps = []
|
||||
const marker = 'ADMIN-API-20260821123456789'
|
||||
const state = { warehouse: null, quote: null, exchange: null, vehicle: null }
|
||||
const context = {
|
||||
marker, calls, coverageGaps, createdResources: {},
|
||||
apiSuccess(_module, name, response) {
|
||||
assert.equal(response?.http, 200, `${name}: HTTP`)
|
||||
assert.equal(String(response?.body?.code), '200', `${name}: code`)
|
||||
return response.body.data
|
||||
},
|
||||
assert(_module, name, _response, condition, evidence) {
|
||||
assert.equal(Boolean(condition), true, `${name}: ${evidence}`)
|
||||
return true
|
||||
},
|
||||
expectConflict(_module, name, response) {
|
||||
assert.equal(response.http, 200, `${name}: HTTP`)
|
||||
assert.ok(['A0409', '409'].includes(String(response.body?.code)), `${name}: code=${response.body?.code}`)
|
||||
return true
|
||||
},
|
||||
addCoverageGap(module, scenario, name, reason, category, metadata = {}) {
|
||||
coverageGaps.push({ module, scenario, name, reason, category, ...metadata })
|
||||
},
|
||||
async request(method, path, body) {
|
||||
calls.push({ gateway: 'domestic', method, path, body })
|
||||
assert.notEqual(method, 'DELETE')
|
||||
if (method === 'POST' && path === DOMESTIC_BASE) {
|
||||
state.warehouse = { ...body, id: '910000000000000001' }
|
||||
return ok(state.warehouse.id)
|
||||
}
|
||||
if (method === 'GET' && path === `${DOMESTIC_BASE}/910000000000000001?tenantId=0`) {
|
||||
return ok({ warehouse: { ...state.warehouse }, addresses: [state.warehouse.address], capabilities: state.warehouse.capabilities })
|
||||
}
|
||||
if (method === 'PUT' && path === `${DOMESTIC_BASE}/910000000000000001?tenantId=0`) {
|
||||
state.warehouse = { ...body, id: state.warehouse.id }
|
||||
return ok(null)
|
||||
}
|
||||
if (method === 'PATCH' && path === `${DOMESTIC_BASE}/910000000000000001/status?tenantId=0&status=INACTIVE`) {
|
||||
state.warehouse.status = 'INACTIVE'
|
||||
return ok(null)
|
||||
}
|
||||
assert.fail(`unexpected domestic call ${method} ${path}`)
|
||||
},
|
||||
async requestOverseas(method, path, body) {
|
||||
calls.push({ gateway: 'overseas', method, path, body })
|
||||
assert.notEqual(method, 'DELETE')
|
||||
if (method === 'GET' && path === `${OVERSEAS_BASE}/overseas-quotes/warehouse-options`) {
|
||||
return ok([{ warehouseId: '910000000000000001', warehouseCode: state.warehouse.warehouseCode,
|
||||
warehouseName: state.warehouse.warehouseName, countryCode: 'US' }])
|
||||
}
|
||||
if (method === 'POST' && path === `${OVERSEAS_BASE}/overseas-quotes`) {
|
||||
state.quote = {
|
||||
summary: { id: '920000000000000001', ...body, warehouseCode: state.warehouse.warehouseCode,
|
||||
warehouseName: state.warehouse.warehouseName, countryCode: 'US', status: 'INACTIVE', recordVersion: 0 },
|
||||
warehouseFees: body.warehouseFees, transitPrices: body.transitPrices || [],
|
||||
}
|
||||
return ok(detailQuote(state.quote))
|
||||
}
|
||||
if (path === `${OVERSEAS_BASE}/overseas-quotes/920000000000000001`) {
|
||||
if (method === 'GET') return ok(detailQuote(state.quote))
|
||||
if (method === 'PUT') {
|
||||
if (Number(body.recordVersion) !== state.quote.summary.recordVersion) return conflict()
|
||||
state.quote.summary = { ...state.quote.summary, name: body.name, providerName: body.providerName,
|
||||
currency: body.currency, effectiveStart: body.effectiveStart, effectiveEnd: body.effectiveEnd,
|
||||
remark: body.remark, recordVersion: state.quote.summary.recordVersion + 1 }
|
||||
state.quote.warehouseFees = body.warehouseFees
|
||||
state.quote.transitPrices = body.transitPrices || []
|
||||
return ok(detailQuote(state.quote))
|
||||
}
|
||||
}
|
||||
if (method === 'PATCH' && path === `${OVERSEAS_BASE}/overseas-quotes/920000000000000001/status`) {
|
||||
assert.equal(Number(body.recordVersion), state.quote.summary.recordVersion)
|
||||
state.quote.summary.status = body.status
|
||||
state.quote.summary.recordVersion += 1
|
||||
return ok(detailQuote(state.quote))
|
||||
}
|
||||
if (method === 'GET' && path.startsWith(`${OVERSEAS_BASE}/exchange-rates?page=1&size=20&monthFrom=`)) {
|
||||
return ok({ records: [], page: 1, size: 20, total: 0, pages: 0 })
|
||||
}
|
||||
if (method === 'POST' && path === `${OVERSEAS_BASE}/exchange-rates`) {
|
||||
state.exchange = { ...body, baseCurrency: 'USD', quoteCurrency: 'CNY', status: 'ACTIVE', recordVersion: 0 }
|
||||
return ok({ ...state.exchange })
|
||||
}
|
||||
if (state.exchange && path === `${OVERSEAS_BASE}/exchange-rates/${state.exchange.month}`) {
|
||||
if (method === 'GET') return ok({ ...state.exchange })
|
||||
if (method === 'PUT') {
|
||||
if (Number(body.recordVersion) !== state.exchange.recordVersion) return conflict()
|
||||
state.exchange = { ...state.exchange, usdToCnyAverage: body.usdToCnyAverage,
|
||||
remark: body.remark, recordVersion: state.exchange.recordVersion + 1 }
|
||||
return ok({ ...state.exchange })
|
||||
}
|
||||
}
|
||||
if (state.exchange && method === 'PATCH' && path === `${OVERSEAS_BASE}/exchange-rates/${state.exchange.month}/status`) {
|
||||
assert.equal(Number(body.recordVersion), state.exchange.recordVersion)
|
||||
state.exchange = { ...state.exchange, status: body.status, remark: body.remark ?? state.exchange.remark,
|
||||
recordVersion: state.exchange.recordVersion + 1 }
|
||||
return ok({ ...state.exchange })
|
||||
}
|
||||
if (method === 'POST' && path === `${OVERSEAS_BASE}/vehicles`) {
|
||||
state.vehicle = { id: '930000000000000001', ...body, recordVersion: 0 }
|
||||
return ok(vehicleWire(state))
|
||||
}
|
||||
if (path === `${OVERSEAS_BASE}/vehicles/930000000000000001`) {
|
||||
if (method === 'GET') return ok(vehicleWire(state))
|
||||
if (method === 'PUT') {
|
||||
if (Number(body.recordVersion) !== state.vehicle.recordVersion) return conflict()
|
||||
state.vehicle = { ...state.vehicle, ...body, recordVersion: state.vehicle.recordVersion + 1,
|
||||
status: state.vehicle.status }
|
||||
return ok(vehicleWire(state))
|
||||
}
|
||||
}
|
||||
if (method === 'PATCH' && path === `${OVERSEAS_BASE}/vehicles/930000000000000001/status`) {
|
||||
assert.equal(Number(body.recordVersion), state.vehicle.recordVersion)
|
||||
state.vehicle = { ...state.vehicle, status: body.status, recordVersion: state.vehicle.recordVersion + 1 }
|
||||
return ok(vehicleWire(state))
|
||||
}
|
||||
assert.fail(`unexpected overseas call ${method} ${path}`)
|
||||
},
|
||||
async requestOverseasBinary(method, path) {
|
||||
calls.push({ gateway: 'overseas-binary', method, path })
|
||||
assert.equal(method, 'GET')
|
||||
assert.match(path, /\/(?:overseas-quotes|exchange-rates|vehicles)\/export\?/)
|
||||
return { method, path, http: 200, body: null, bytes: new TextEncoder().encode('id,status\n1,ACTIVE\n'),
|
||||
contentType: 'text/csv;charset=UTF-8', requestId: 'req-csv' }
|
||||
},
|
||||
}
|
||||
return { context, state }
|
||||
}
|
||||
|
||||
test('静态锁定真实双Gateway生命周期、CSV与安全边界', () => {
|
||||
assert.match(source, /context\.request\('POST', DOMESTIC_BASE/)
|
||||
assert.match(source, /warehouseType: 'OVERSEAS_PARTNER'/)
|
||||
assert.match(source, /context\.requestOverseas\('POST'/)
|
||||
assert.match(source, /context\.requestOverseas\('PUT'/)
|
||||
assert.match(source, /context\.requestOverseas\('PATCH'/)
|
||||
assert.match(source, /context\.requestOverseasBinary\('GET'/)
|
||||
assert.match(source, /context\.expectConflict/)
|
||||
assert.match(source, /finally\s*\{/)
|
||||
assert.match(source, /context\.createdResources\.phase4OverseasMasterData/)
|
||||
assert.match(source, /context\.addCoverageGap/)
|
||||
assert.match(source, /2090 \+ Math\.floor/)
|
||||
assert.doesNotMatch(source, /\/internal\/|overseas-partners|https?:\/\/|fetch\(|process\.env|request(?:Overseas)?\('DELETE'/)
|
||||
for (const endpoint of ['overseas-quotes/warehouse-options', 'overseas-quotes/export',
|
||||
'exchange-rates/export', 'vehicles/export']) assert.ok(source.includes(endpoint))
|
||||
})
|
||||
|
||||
test('marker资源完成创建、详情、编辑、冲突、状态、CSV并全部停用', async () => {
|
||||
const { context, state } = fakeContext()
|
||||
await run(context)
|
||||
const resource = context.createdResources.phase4OverseasMasterData
|
||||
assert.equal(resource.partnerWarehouse.id, '910000000000000001')
|
||||
assert.equal(resource.partnerWarehouse.finalStatus, 'INACTIVE')
|
||||
assert.equal(resource.quote.id, '920000000000000001')
|
||||
assert.equal(resource.quote.finalStatus, 'INACTIVE')
|
||||
assert.match(resource.exchangeRate.month, /^209\d-(0[1-9]|1[0-2])$/)
|
||||
assert.equal(resource.exchangeRate.finalStatus, 'INACTIVE')
|
||||
assert.equal(resource.vehicle.id, '930000000000000001')
|
||||
assert.equal(resource.vehicle.finalStatus, 'INACTIVE')
|
||||
assert.equal(typeof resource.vehicle.recordVersion, 'number')
|
||||
assert.equal(state.warehouse.status, 'INACTIVE')
|
||||
assert.equal(state.quote.summary.status, 'INACTIVE')
|
||||
assert.equal(state.exchange.status, 'INACTIVE')
|
||||
assert.equal(state.vehicle.status, 'INACTIVE')
|
||||
assert.equal(context.calls.filter((call) => call.gateway === 'overseas-binary').length, 3)
|
||||
assert.equal(context.calls.filter((call) => call.method === 'DELETE').length, 0)
|
||||
assert.equal(context.calls.filter((call) => call.method === 'PUT').length, 7)
|
||||
})
|
||||
|
||||
test('候选空缓存登记覆盖缺口并继续汇率车辆,finally停用国内合作仓', async () => {
|
||||
const { context, state } = fakeContext()
|
||||
const original = context.requestOverseas
|
||||
context.requestOverseas = async (method, path, body) => {
|
||||
if (method === 'GET' && path.endsWith('/overseas-quotes/warehouse-options')) return ok([])
|
||||
return original(method, path, body)
|
||||
}
|
||||
await run(context)
|
||||
assert.equal(state.warehouse.status, 'INACTIVE')
|
||||
assert.equal(state.quote, null)
|
||||
assert.equal(state.exchange.status, 'INACTIVE')
|
||||
assert.equal(state.vehicle.status, 'INACTIVE')
|
||||
assert.equal(context.createdResources.phase4OverseasMasterData.quote.skipped, true)
|
||||
assert.equal(context.createdResources.phase4OverseasMasterData.partnerWarehouse.finalStatus, 'INACTIVE')
|
||||
assert.equal(context.createdResources.phase4OverseasMasterData.exchangeRate.finalStatus, 'INACTIVE')
|
||||
assert.equal(context.createdResources.phase4OverseasMasterData.vehicle.finalStatus, 'INACTIVE')
|
||||
assert.equal(context.coverageGaps.length, 1)
|
||||
assert.equal(context.coverageGaps[0].name, '海外报价完整写生命周期')
|
||||
assert.equal(context.coverageGaps[0].category, 'deployment-prerequisite')
|
||||
assert.match(context.coverageGaps[0].reason, /30分钟空缓存/)
|
||||
assert.equal(context.calls.filter((call) => call.gateway === 'overseas-binary').length, 2)
|
||||
})
|
||||
Reference in New Issue
Block a user