import test from 'node:test' import assert from 'node:assert/strict' import { pickDispatchItem } from '../src/api/fulfillment.js' import { session } from '../src/stores/session.js' const path = '/api/pda/v1/last-leg/storage-rent/preparations' const pick = '/api/pda/v1/last-leg/dispatches/PC1/items/9007199254740995/pick' const body = { recordVersion: '9007199254740993', positionId: '9007199254740994', packages: 2, productQuantity: 0, cartonMark: null, idempotencyKey: 'dispatch-rent-1' } const ready = { data: { preparationId: 'rent1', ready: true, status: 'READY' } } const pending = { data: { preparationId: 'rent1', ready: false, status: 'FREEZE_PENDING' } } const submit = () => pickDispatchItem('PC1', '9007199254740995', body) function transport(responses) { const calls = []; session.apiBase = '/api'; session.token = 'overseas-token' globalThis.uni = { request(options) { calls.push({ method: options.method, url: options.url, data: options.data }) const response = responses.shift(); assert.ok(response, 'unexpected request') if (response.network) return options.fail({ errMsg: 'network down' }) options.success({ statusCode: 200, data: { code: '200', ...response }, header: {} }) } } return calls } test('排车仓租与实际拣货绑定同一来源、数量和幂等键,保持长ID精度', async () => { const calls = transport([ready, { data: { success: true } }]); await submit() assert.deepEqual(calls, [ { method: 'POST', url: path, data: { mode: 'DISPATCH', businessNo: 'PC1', itemId: '9007199254740995', positionId: body.positionId, packages: 2, cartonMark: null, idempotencyKey: body.idempotencyKey, productQuantity: 0 } }, { method: 'POST', url: pick, data: body } ]) }) test('免租或不计租仍按后端就绪结果继续,非布尔就绪禁止拣货', async () => { const calls = transport([{ data: { ready: true, status: 'NOT_REQUIRED' } }, { data: {} }]); await submit(); assert.equal(calls.at(-1).url, pick) const blocked = transport([{ data: { ready: 'true' } }]); await assert.rejects(submit(), /预校验/); assert.equal(blocked.length, 1) }) test('预占待回执只读查询,就绪后仅发一次拣货', async t => { t.mock.method(globalThis, 'setTimeout', callback => { callback(); return 0 }) const calls = transport([pending, ready, { data: {} }]); await submit() assert.deepEqual(calls.map(c => [c.method, c.url]), [['POST', path], ['GET', path + '/rent1'], ['POST', pick]]) }) test('资金失败释放预占;预校验404或断网不绕过,不发拣货', async () => { const calls = transport([{ data: { preparationId: 'rent1', ready: false, status: 'FAILED', message: '余额不足' } }, { data: {} }]) await assert.rejects(submit(), /余额不足/); assert.deepEqual(calls.map(c => c.method), ['POST', 'DELETE']) for (const failure of [{ code: 'A0404', message: 'missing', requestId: 'req1' }, { network: true }]) { const failed = transport([failure]); await assert.rejects(submit(), e => failure.network ? e.network : e.code === failure.code && e.requestId === 'req1'); assert.equal(failed.length, 1) } }) test('拣货请求发出后结果不明,不重发也不释放可能已消费的预占', async () => { const calls = transport([ready, { network: true }]); await assert.rejects(submit(), e => e.network) assert.deepEqual(calls.map(c => c.method), ['POST', 'POST']) })