import test from 'node:test' import assert from 'node:assert/strict' import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { createCompletedOrder, transition } from './order-inbound-status-fixtures.mjs' test('dynamic Platform cancellation freezes version and key while reject body stays unchanged',async()=>{ const calls=[] const context={marker:'fixture',token:'admin',apiSuccess(_m,_n,r){assert.equal(r.body.code,'200');return r.body.data}, async request(method,path,body,token,headers){calls.push({method,path,body,token,headers});return {http:200,body:{code:'200',data:{order:{version:9}}}}}} await transition(context,'merchant',{tenantId:'2'},'1','CANCELLED','cancel') const command=calls.find(row=>row.method==='POST') assert.equal(command.token,'admin');assert.equal(command.body.expectedVersion,9);assert.ok(command.headers['Idempotency-Key']) calls.length=0 await transition(context,'merchant',{tenantId:'2'},'1','REJECTED','reject') assert.equal(calls.length,1);assert.deepEqual(calls[0].body,{reason:'fixture 保留 REJECTED 人工样本'}) }) const here = path.dirname(fileURLToPath(import.meta.url)) const source = fs.readFileSync(path.join(here, 'order-inbound-status-fixtures.mjs'), 'utf8') test('完成样本来自真实履约编排且缺证据或客户漂移均阻断', async () => { const context = { context: { phase4ReceivingEvidenceReader() {} }, createdResources: { orders: { orderId: '11' } } } const prepare = async scope => { scope.context.merchantQualificationFixture = { tenantId: '7' } } const run = proof => async scope => { assert.equal(scope.context.f40SignatureOrder, 'ROOT_FIRST') assert.equal(scope.context.phase4ReceivingEvidenceReader, context.context.phase4ReceivingEvidenceReader) scope.createdResources.phase5RootFulfillment = proof } assert.deepEqual(await createCompletedOrder(context, run({ finalStatus: 'VERIFIED', customerId: '7', rootOrderId: '99' }), prepare), { orderId: '99', tenantId: '7' }) assert.equal(context.createdResources.orders.orderId, '11') assert.equal(context.createdResources.phase5RootFulfillment, undefined) for (const proof of [{ finalStatus: 'HTTP_VERIFIED_OUTBOX_PENDING', customerId: '7', rootOrderId: '99' }, { finalStatus: 'VERIFIED', customerId: '8', rootOrderId: '99' }]) { await assert.rejects(createCompletedOrder(context, run(proof), prepare), /真实签收/) } assert.doesNotMatch(source, /'start', 'complete'/) assert.match(source, /phase5-root-fulfillment\.mjs/) }) test('为头程订单列表八个真实状态分别创建独立样本', () => { for (const status of ['DRAFT', 'SUBMITTED', 'REJECTED', 'APPROVED', 'ACCEPTED', 'PROCESSING', 'COMPLETED', 'CANCELLED']) { assert.match(source, new RegExp(`\\['${status}', \\[`)) assert.match(source, new RegExp(`result\\.orders\\[target\\]`)) } assert.match(source, /status=\$\{status\}/) assert.match(source, /筛选结果包含人工样本/) }) test('所有写入均走订单生命周期 HTTP API 且不清理保留数据', () => { assert.match(source, /\/api\/merchant\/v1\/orders\/first-leg/) assert.match(source, /\/api\/platform\/v1\/orders\/first-leg/) assert.match(source, /'Idempotency-Key': key\(context,/) assert.doesNotMatch(source, /\b(?:INSERT|UPDATE|DELETE|TRUNCATE)\b/i) assert.doesNotMatch(source, /cleanup|remove|unlink/i) }) test('状态矩阵复用订单共享的逐仓真实报价选择,不假设首仓或首税制', () => { assert.match(source, /findPricedOrderRouteAcrossOrigins/) assert.match(source, /loadChannels: \(receiving\)/) assert.match(source, /pricing\/estimate/) assert.doesNotMatch(source, /rows\(.*domestic.*\)\[0\]/) assert.doesNotMatch(source, /pricingTaxModes\[0\]/) assert.match(source, /pricingTaxMode: priced\.priced\.pricingTaxMode/) }) test('入库通过真实订单测量链保留测量态并最终进入 WAIT_SPLIT', () => { assert.match(source, /result\.inbounds\.WAIT_MEASURE/) assert.match(source, /processStatus: 'WAIT_MEASURE'/) for (const status of ['MEASURING', 'MEASURE_PENDING', 'WAIT_SPLIT']) { assert.match(source, new RegExp(`'${status}'`)) } assert.match(source, /\.\/inbound-measurement\.mjs/) assert.doesNotMatch(source, /recordCoverageGap|addCoverageGap/) }) test('FBA 状态样本为订单头和每条货物行提供四个必填标识', () => { assert.match(source, /const shipmentId = `MANUAL-/) assert.match(source, /const referenceId = `STATUS-/) assert.match(source, /const upcNo =/) assert.match(source, /upcNo, shipmentId, referenceId/) }) test('测量状态截停发生在正确的 HTTP 边界', () => { assert.match(source, /includes\(summary\.mainStatus\)/) assert.doesNotMatch(source, /includes\(summary\.processStatus\)/) assert.match(source, /target === 'MEASURING'/) assert.match(source, /\.\/inbound-weight-ocr\.mjs/) assert.match(source, /await weightOcr\.run\(context\)/) assert.match(source, /target !== 'MEASURING'/) assert.doesNotMatch(source, /target === 'MEASURING' && ok\(response\)/) assert.match(source, /target === 'MEASURE_PENDING' && isSubmit/) assert.doesNotMatch(source, /target === 'MEASURE_REJECTED' && isSubmit/) }) test('入库模块只声明状态全集且不在后续专项生成前预写失败步骤', () => { for (const status of ['WAIT_PRICING', 'FEE_CONFIRMING', 'INBOUNDING', 'VOIDED']) { assert.match(source, new RegExp(`'${status}'`)) } assert.match(source, /processStatus=WAIT_SPLIT/) assert.match(source, /查询存量 WAIT_SPLIT 样本/) assert.doesNotMatch(source, /覆盖阻断|fixture-unavailable|recordCoverageGap|addCoverageGap/) }) test('统一订单声明完整状态集合并由总矩阵统一冻结不可达状态', () => { assert.match(source, /result\.unifiedOrders\.PENDING_REVIEW/) assert.match(source, /result\.unifiedOrders\.WAIT_MEASURE/) for (const status of ['WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED']) { assert.match(source, new RegExp(`'${status}'`)) } assert.doesNotMatch(source, /WAIT_SPLIT 标记为历史废弃状态/) assert.doesNotMatch(source, /没有完成派送并写 DELIVERED/) }) test('按总门禁格式写入 matrix.pages 的 requiredStatuses 和 fixtures', () => { assert.match(source, /run\(context, matrix = context\.createdResources\.manualStateMatrix\)/) for (const page of ['firstLegOrders', 'inbounds', 'unifiedOrders']) { assert.match(source, new RegExp(`matrix\\.pages\\.${page} = \\{ requiredStatuses:`)) } assert.match(source, /detailPath: `\/orders\/\$\{orderId\}`/) })