fix: align audit and dispatch workflows and release failed requests
This commit is contained in:
@@ -46,15 +46,15 @@ it('does not accept a receipt while the warehouse is still waiting for actual go
|
||||
const wrapper = mount('receipt'); await flushPromises(); wrapper.findComponent({ name: 'AppDialog' }).vm.$emit('confirm'); await flushPromises()
|
||||
expect(api.acceptTripIncoming).not.toHaveBeenCalled(); expect(wrapper.findComponent({ name: 'AppDialog' }).props('confirmDisabled')).toBe(true)
|
||||
})
|
||||
it('retries the same incoming registration after an uncertain result without creating a new command', async () => {
|
||||
it('submits a fresh incoming registration after failure', async () => {
|
||||
vi.mocked(api.startTripIncoming).mockRejectedValueOnce(new Error('network')).mockResolvedValueOnce({ tripRecordVersion: 5, booking, replayed: true })
|
||||
const wrapper = mount('incoming'); await flushPromises(); wrapper.findComponent({ name: 'AppDialog' }).vm.$emit('confirm'); await flushPromises()
|
||||
const first = vi.mocked(api.startTripIncoming).mock.calls[0]![2]
|
||||
wrapper.findComponent({ name: 'AppDialog' }).vm.$emit('confirm'); await flushPromises()
|
||||
expect(api.startTripIncoming).toHaveBeenNthCalledWith(2, 'TR-1', 'FB-1', first); expect(api.getTripIncoming).not.toHaveBeenCalled()
|
||||
expect(api.startTripIncoming).toHaveBeenNthCalledWith(2, 'TR-1', 'FB-1', { ...first, idempotencyKey: expect.any(String) }); expect(vi.mocked(api.startTripIncoming).mock.calls[1]![2].idempotencyKey).not.toBe(first.idempotencyKey); expect(api.getTripIncoming).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('keeps an uncertain receipt command retryable after closing and reopening without reloading or changing its hash', async () => {
|
||||
it('reloads current receipt on reopening and submits a fresh command', async () => {
|
||||
vi.mocked(api.acceptTripIncoming).mockRejectedValueOnce(new Error('network')).mockResolvedValueOnce({ tripRecordVersion: 6, booking: { ...booking, status: 'RECEIVED' }, replayed: true })
|
||||
const wrapper=mount('receipt'); await flushPromises()
|
||||
wrapper.findComponent({ name: 'AppDialog' }).vm.$emit('confirm'); await flushPromises()
|
||||
@@ -62,8 +62,8 @@ it('keeps an uncertain receipt command retryable after closing and reopening wit
|
||||
await wrapper.setProps({ modelValue: false }); await wrapper.setProps({ modelValue: true }); await flushPromises()
|
||||
expect(wrapper.findComponent({ name: 'AppDialog' }).props('confirmDisabled')).toBe(false)
|
||||
wrapper.findComponent({ name: 'AppDialog' }).vm.$emit('confirm'); await flushPromises()
|
||||
expect(api.acceptTripIncoming).toHaveBeenNthCalledWith(2, 'TR-1', 'FB-1', original)
|
||||
expect(api.getTripIncoming).toHaveBeenCalledOnce()
|
||||
expect(api.acceptTripIncoming).toHaveBeenNthCalledWith(2, 'TR-1', 'FB-1', { ...original, idempotencyKey: expect.any(String) }); expect(vi.mocked(api.acceptTripIncoming).mock.calls[1]![2].idempotencyKey).not.toBe(original.idempotencyKey)
|
||||
expect(api.getTripIncoming).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it.each([
|
||||
@@ -136,7 +136,7 @@ it('requires explicit acceptance of a changed received snapshot and submits the
|
||||
expect(api.acceptTripIncoming).toHaveBeenCalledExactlyOnceWith('TR-1', 'FB-1', { tripRecordVersion: 11, recordVersion: 8, idempotencyKey: expect.any(String), receiptHash: 'merged-hash', unitPrice: 50, pallets: [{ warehousePalletId: '903', palletSpaces: 1 }] })
|
||||
})
|
||||
|
||||
it('uses a new key after a completed confirmation while preserving the original key for unknown retries', async () => {
|
||||
it('uses a new key after a completed confirmation and after failed requests', async () => {
|
||||
vi.mocked(api.acceptTripIncoming).mockResolvedValue({ tripRecordVersion: 6, booking: { ...booking, status: 'RECEIVED' }, replayed: false })
|
||||
const wrapper = mount('receipt'); await flushPromises()
|
||||
wrapper.findComponent({ name: 'AppDialog' }).vm.$emit('confirm'); await flushPromises()
|
||||
@@ -174,7 +174,7 @@ it.each(['bound', 'departed', 'permission'] as const)('rejects a receipt write i
|
||||
expect(wrapper.findComponent({ name: 'AppDialog' }).props('confirmDisabled')).toBe(true)
|
||||
})
|
||||
|
||||
it('requires new measurements for changed pallet composition and keeps them in the exact unknown-result retry', async () => {
|
||||
it('requires measurements for changed pallet composition and submits them with a new key after failure', async () => {
|
||||
const merged = { ...preview, incoming: { ...preview.incoming!, status: 'READY_FOR_DISPATCH', receiptHash: 'merged-null-measurement', pallets: [{ warehousePalletId: '903', palletNo: 'MERGED-1', packages: 22, weightKg: null, volumeCbm: null }] } }
|
||||
vi.mocked(api.getTripIncoming).mockResolvedValue(merged)
|
||||
vi.mocked(api.acceptTripIncoming).mockRejectedValueOnce(new Error('network')).mockResolvedValueOnce({ tripRecordVersion: 6, booking: { ...booking, status: 'RECEIVED' }, replayed: true })
|
||||
@@ -190,7 +190,7 @@ it('requires new measurements for changed pallet composition and keeps them in t
|
||||
const original = vi.mocked(api.acceptTripIncoming).mock.calls[0]![2]
|
||||
expect(original).toMatchObject({ receiptHash: 'merged-null-measurement', pallets: [{ warehousePalletId: '903', palletSpaces: 1, weightKg: 123.456, volumeCbm: 1.234 }] })
|
||||
confirm(); await flushPromises()
|
||||
expect(api.acceptTripIncoming).toHaveBeenNthCalledWith(2, 'TR-1', 'FB-1', original)
|
||||
expect(api.acceptTripIncoming).toHaveBeenNthCalledWith(2, 'TR-1', 'FB-1', { ...original, idempotencyKey: expect.any(String) }); expect(vi.mocked(api.acceptTripIncoming).mock.calls[1]![2].idempotencyKey).not.toBe(original.idempotencyKey)
|
||||
})
|
||||
|
||||
it('does not offer measurement overrides for unchanged source pallets', async () => {
|
||||
|
||||
Reference in New Issue
Block a user