import test from 'node:test' import assert from 'node:assert/strict' import { cartonTotals, normalizeOrderInput, measurementPlan, assertConfirmedWeight } from './prod-release-measurement-plan.mjs' const pallet = { id: '10', warehouseId: '20', palletCode: 'FIXTURE-A', capacityCbm: '1.200000', weightKg: '8.000' } const plan = (patch = {}) => measurementPlan({ packageCount: 2, warehouseId: '20', pallets: [pallet], allowedCodes: ['FIXTURE-A'], ...patch }) test('agreed carton profile: 7.5kg, 40x30x30cm', () => { assert.deepEqual(cartonTotals(2), { packageCount: 2, lengthCm: 40, widthCm: 30, heightCm: 30, grossWeightKg: 15, volumeCbm: 0.072 }) assert.equal(cartonTotals(1).volumeCbm, 0.036) for (const count of [0, -1, 3, 1.5, '2', NaN]) assert.throws(() => cartonTotals(count)) }) test('declaration normalization preserves product facts and never mutates source', () => { const input = { payload: { cargoes: [{ packageCount: 2, skuNo: 'fixture', grossWeightKg: 500, netWeightKg: 12 }] } } const normalized = normalizeOrderInput(input) assert.equal(normalized.payload.cargoes[0].grossWeightKg, 15) assert.equal(normalized.payload.cargoes[0].skuNo, 'fixture') assert.equal(normalized.payload.cargoes[0].netWeightKg, 12) assert.equal(input.payload.cargoes[0].grossWeightKg, 500) assert.throws(() => normalizeOrderInput({ payload: { cargoes: [{ packageCount: 1, netWeightKg: 8 }] } }), /净重/) }) test('two cartons on existing 8kg tare pallet: scale 23kg, cargo 15kg', () => { const result = plan() assert.equal(result.palletCount, 1) assert.equal(result.weightGrossTotalKg, 23) assert.equal(result.weights[0].netWeightKg, 15) assert.equal(result.measurementWritten, false) assert.equal(result.fullFlowVerified, false) }) test('exact volume boundaries use decimal integer arithmetic', () => { assert.equal(plan({ pallets: [{ ...pallet, capacityCbm: '0.072000' }] }).palletCount, 1) const result = plan({ pallets: [{ ...pallet, capacityCbm: '0.071999' }] }) assert.equal(result.palletCount, 2) assert.equal(result.weights.reduce((sum, item) => sum + item.packageCount, 0), 2) assert.equal(result.weightGrossTotalKg, 31) assert.ok(result.weights.every(w => w.palletId === pallet.id)) }) test('missing capacity or tare never falls back to a fabricated default', () => { for (const changes of [{ capacityCbm: 0 }, { capacityCbm: undefined }, { capacityCbm: '0.0000001' }, { weightKg: null }, { weightKg: -1 }, { warehouseId: '99' }, { id: 10 }]) { assert.throws(() => plan({ pallets: [{ ...pallet, ...changes }] })) } assert.equal(plan({ pallets: [{ ...pallet, weightKg: 0 }] }).weightGrossTotalKg, 15) }) test('missing/duplicate allowlisted pallet fails; no automatic substitute', () => { assert.throws(() => plan({ allowedCodes: [] })) assert.throws(() => plan({ allowedCodes: ['FIXTURE-A', 'MISSING'] })) assert.throws(() => plan({ pallets: [pallet, pallet] })) assert.throws(() => plan({ pallets: [{ ...pallet, capacityCbm: '0.035' }] }), /完整箱/) }) test('confirmed weights must preserve tare and cargo totals', () => { const expected = plan().weights[0] assert.doesNotThrow(() => assertConfirmedWeight({ ...expected, recognitionStatus: 'CONFIRMED' }, expected)) for (const patch of [{ palletId: '99' }, { recognitionStatus: 'NEEDS_MANUAL' }, { grossWeightKg: 15 }, { netWeightKg: 7 }, { palletTareWeightKg: 0 }]) { assert.throws(() => assertConfirmedWeight({ ...expected, recognitionStatus: 'CONFIRMED', ...patch }, expected)) } })