From 8c1905418e9c4dbd776233ef1efa50c5c614d9c2 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Fri, 2 Oct 2026 21:46:39 +0800 Subject: [PATCH] test(order): accept omitted identifiers on failed import rows --- ...ient-test-env-acceptance-contract.test.mjs | 23 +++++++++++++++++-- scripts/client-test-env-acceptance.mjs | 4 +++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/scripts/client-test-env-acceptance-contract.test.mjs b/scripts/client-test-env-acceptance-contract.test.mjs index 32662a731..b10c36c3f 100644 --- a/scripts/client-test-env-acceptance-contract.test.mjs +++ b/scripts/client-test-env-acceptance-contract.test.mjs @@ -69,6 +69,25 @@ test('partial import validates physical row, exact counts, failure details and i } }) +test('PARTIAL wire response accepts only null or omitted failed-row identifiers', () => { + const r = runtime() + // Shape captured from r1: Jackson omits all null fields on both failed and successful rows. + const wire = JSON.parse('{"mode":"PARTIAL","batchNo":"OBI-contract","sourceFileId":"101","errorReportFileId":"102","result":{"total":2,"succeeded":1,"failed":1,"items":[{"index":0,"clientRowId":"excel-row-3","success":false,"errorCode":"A0422","errorMessage":"货物名称不能为空"},{"index":1,"clientRowId":"excel-row-4","success":true,"orderId":"2106016937331458049","orderNo":"FL2106016937331458049"}]}}') + r.assertImportResult(wire, 'PARTIAL', [false, true]) + for (const field of ['orderId', 'orderNo', 'inboundCode']) { + const explicitNull = structuredClone(wire); explicitNull.result.items[0][field] = null + r.assertImportResult(explicitNull, 'PARTIAL', [false, true]) + for (const value of ['2106016937331458049', 'FL-example', 'NYEXX-example', '', 0, false, NaN, [], {}]) { + const invalid = structuredClone(wire); invalid.result.items[0][field] = value + assert.throws(() => r.assertImportResult(invalid, 'PARTIAL', [false, true]), new RegExp(`no ${field}`)) + } + } + for (const field of ['orderId', 'orderNo']) { + const missingSuccess = structuredClone(wire); delete missingSuccess.result.items[1][field] + assert.throws(() => r.assertImportResult(missingSuccess, 'PARTIAL', [false, true]), /created order/) + } +}) + function templateFixture(r) { return new Map([ ['xl/workbook.xml', ''], @@ -213,9 +232,9 @@ function importHarness(fault = '') { const masterData = { receiving: { id: 'domestic', warehouseName: '国内仓', warehouseCode: 'CN' }, destination: { id: 'fba', warehouseName: '目的仓', warehouseCode: 'US' }, channel: { channelName: '海运渠道', channelCode: 'SEA' } } let nextKey = 0, r - const resultItem = (index, success, orderId) => ({ index, clientRowId: `excel-row-${index + 3}`, success, + const resultItem = (index, success, orderId) => Object.fromEntries(Object.entries({ index, clientRowId: `excel-row-${index + 3}`, success, orderId: success ? orderId : null, orderNo: success ? `FL${orderId}` : null, - errorCode: success ? null : 'A0422', errorMessage: success ? null : 'cargo required' }) + errorCode: success ? null : 'A0422', errorMessage: success ? null : 'cargo required' }).filter(([, value]) => value !== null)) const responseData = (mode, items) => ({ mode, batchNo: 'batch', sourceFileId: 'source-file', errorReportFileId: 'error-file', result: { total: items.length, succeeded: items.filter(item => item.success).length, failed: items.filter(item => !item.success).length, items } }) const addDraft = (id, cells) => orders.set(id, { order: { id, orderNo: `FL${id}`, version: 0, status: 'DRAFT', tenantId: 'tenant', diff --git a/scripts/client-test-env-acceptance.mjs b/scripts/client-test-env-acceptance.mjs index a127030f5..873d730b3 100644 --- a/scripts/client-test-env-acceptance.mjs +++ b/scripts/client-test-env-acceptance.mjs @@ -2045,7 +2045,9 @@ function assertImportResult(data, mode, expected) { assertEqual(item.success, expected[index], 'row success') if (item.success) { assertPresent(item.orderId, 'created order ID'); assertPresent(item.orderNo, 'created order number') } else { - assertEqual(item.orderId, null, 'failed row has no order') + for (const field of ['orderId', 'orderNo', 'inboundCode']) { + assertTrue(item[field] === null || item[field] === undefined, `failed row has no ${field}`) + } assertEqual(item.errorCode, 'A0422', 'invalid row code') assertPresent(item.errorMessage, 'row error reason') }