fix: align audit and dispatch workflows and release failed requests

This commit is contained in:
2026-10-22 23:10:09 +08:00
parent 9cdcb9c077
commit 4a3456756f
124 changed files with 1296 additions and 2120 deletions
@@ -19,7 +19,7 @@ beforeEach(() => {
vi.mocked(recoverVehiclePhoto).mockResolvedValue(photo)
vi.mocked(bindVehiclePhoto).mockResolvedValue({ ...response('4'), photos: [{ ...photo, savedAt: '2026-10-21T00:00:00Z' }] })
})
it('binds the uploaded file to the car and restores the original binding after reopening without uploading twice', async () => {
it('does not restore failed bindings after reopening and allows a new upload', async () => {
vi.mocked(bindVehiclePhoto).mockRejectedValueOnce(new Error('network timeout'))
const first = setup(); await flushPromises(); await upload(first)
const table = first.get('table[aria-label="油耗图片"]')
@@ -29,33 +29,33 @@ it('binds the uploaded file to the car and restores the original binding after r
expect(original).toMatchObject({ recordVersion: '3', fileId: photo.fileId })
first.unmount()
const reopened = setup(); await flushPromises()
await reopened.findAll('button').find(button => button.text() === '核对原请求并继续保存')!.trigger('click'); await flushPromises()
expect(bindVehiclePhoto).toHaveBeenLastCalledWith('PC/1', 'FUEL_START', original)
expect(uploadVehiclePhoto).toHaveBeenCalledTimes(1)
await upload(reopened)
expect(vi.mocked(bindVehiclePhoto).mock.calls[1]![2].idempotencyKey).not.toBe(original.idempotencyKey)
expect(uploadVehiclePhoto).toHaveBeenCalledTimes(2)
expect(reopened.text()).toContain('fuel.png')
expect(reopened.get('table tbody tr').text()).toContain('2026-10-21 00:00:00Z')
expect(sessionStorage.length).toBe(0)
reopened.unmount()
})
it('keeps uncertain uploads for original-key recovery and never resubmits the file', async () => {
it('unlocks uncertain uploads for a new file selection', async () => {
vi.mocked(uploadVehiclePhoto).mockRejectedValueOnce(new Error('connection lost'))
const wrapper = setup(); await flushPromises(); await upload(wrapper)
const originalKey = vi.mocked(uploadVehiclePhoto).mock.calls[0]![3]
await wrapper.findAll('button').find(button => button.text() === '核对原请求并继续保存')!.trigger('click'); await flushPromises()
expect(recoverVehiclePhoto).toHaveBeenCalledWith('PC/1', originalKey)
expect(uploadVehiclePhoto).toHaveBeenCalledTimes(1)
await upload(wrapper)
expect(recoverVehiclePhoto).not.toHaveBeenCalled(); expect(vi.mocked(uploadVehiclePhoto).mock.calls[1]![3]).not.toBe(originalKey)
expect(uploadVehiclePhoto).toHaveBeenCalledTimes(2)
expect(bindVehiclePhoto).toHaveBeenCalledTimes(1)
wrapper.unmount()
})
it('refreshes only a known version conflict and reuses the uploaded file', async () => {
it('allows a new photo and current version after a binding conflict', async () => {
vi.mocked(bindVehiclePhoto).mockRejectedValueOnce(new ApiResponseError('运营记录版本已变化,请刷新后重试', 'A0409', 409))
const wrapper = setup(); await flushPromises(); await upload(wrapper)
const originalKey = vi.mocked(bindVehiclePhoto).mock.calls[0]![2].idempotencyKey
vi.mocked(getVehicleDocuments).mockResolvedValue(response('8'))
await wrapper.findAll('button').find(button => button.text() === '刷新版本并保存已上传图片')!.trigger('click'); await flushPromises()
await upload(wrapper)
expect(bindVehiclePhoto).toHaveBeenLastCalledWith('PC/1', 'FUEL_START', { recordVersion: '8', fileId: photo.fileId, idempotencyKey: expect.any(String) })
expect(vi.mocked(bindVehiclePhoto).mock.calls[1]![2].idempotencyKey).not.toBe(originalKey)
expect(uploadVehiclePhoto).toHaveBeenCalledTimes(1)
expect(uploadVehiclePhoto).toHaveBeenCalledTimes(2)
wrapper.unmount()
})
it('does not offer upload with list permission alone', async () => {