feat(fleet): select versioned sales quotes and isolate cost drafts
This commit is contained in:
@@ -2,6 +2,7 @@ import { afterEach, beforeEach, expect, it, vi } from 'vitest'
|
||||
import { shallowMount, flushPromises, type VueWrapper } from '@vue/test-utils'
|
||||
import TripCostPanel from './TripCostPanel.vue'
|
||||
import * as api from '../api/tripCosts'
|
||||
import { ApiResponseError } from '@/shared/api/http'
|
||||
const access = vi.hoisted(() => ({ read: true, write: true }))
|
||||
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: (permission: string) => permission.endsWith(':list') ? access.read : access.write }) }))
|
||||
vi.mock('element-plus', () => ({ ElMessage: { success: vi.fn(), warning: vi.fn() } }))
|
||||
@@ -21,7 +22,7 @@ function mount() {
|
||||
} } }); wrappers.push(wrapper); return wrapper
|
||||
}
|
||||
function button(w: VueWrapper, label: string) { return w.findAll('button').find(b => b.text() === label)! }
|
||||
beforeEach(() => { vi.clearAllMocks(); access.read = true; access.write = true; vi.mocked(api.listTripCosts).mockResolvedValue(structuredClone(result)); vi.mocked(api.createTripCost).mockResolvedValue(cost); vi.mocked(api.updateTripCost).mockResolvedValue(cost)
|
||||
beforeEach(() => { vi.resetAllMocks(); access.read = true; access.write = true; vi.mocked(api.listTripCosts).mockResolvedValue(structuredClone(result)); vi.mocked(api.createTripCost).mockResolvedValue(cost); vi.mocked(api.updateTripCost).mockResolvedValue(cost)
|
||||
vi.mocked(api.listTripCostHistory).mockResolvedValue({ records: [{ recordVersion: '9', action: 'UPDATE', reason: '更正', occurredAt: cost.updatedAt, snapshot: { cost: { ...cost, recordVersion: '9' }, summary: result.summary } }], page: 1, size: 1, total: 1, pages: 1 }) })
|
||||
afterEach(() => wrappers.splice(0).forEach(w => w.unmount()))
|
||||
it('loads one scoped page and summary without per-row reads or invented zero totals', async () => {
|
||||
@@ -67,7 +68,7 @@ it('keeps the successful save authoritative when pagination changes while it is
|
||||
expect(api.listTripCosts).toHaveBeenLastCalledWith('TR-ONE', 1, 10)
|
||||
expect(api.createTripCost).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
it('does not let an old save clear a new pending save after switching away and back', async () => {
|
||||
it('retains the original request across trip switches and ignores the first response during its retry', async () => {
|
||||
let finishFirst!: (value: api.TripCost) => void
|
||||
let finishSecond!: (value: api.TripCost) => void
|
||||
vi.mocked(api.createTripCost)
|
||||
@@ -77,6 +78,8 @@ it('does not let an old save clear a new pending save after switching away and b
|
||||
w.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 12.5)
|
||||
await button(w, '保存').trigger('click'); await flushPromises()
|
||||
await w.setProps({ tripNo: 'TR-TWO' }); await flushPromises()
|
||||
await button(w, '登记成本').trigger('click'); await flushPromises()
|
||||
expect(w.findAllComponents({ name: 'AppDialog' })[0]!.props('modelValue')).toBe(false)
|
||||
await w.setProps({ tripNo: 'TR-ONE' }); await flushPromises()
|
||||
await button(w, '登记成本').trigger('click'); await flushPromises()
|
||||
w.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 20)
|
||||
@@ -84,9 +87,22 @@ it('does not let an old save clear a new pending save after switching away and b
|
||||
finishFirst(cost); await flushPromises()
|
||||
await button(w, '保存').trigger('click'); await flushPromises()
|
||||
expect(api.createTripCost).toHaveBeenCalledTimes(2)
|
||||
expect(vi.mocked(api.createTripCost).mock.calls[1]).toEqual(vi.mocked(api.createTripCost).mock.calls[0])
|
||||
finishSecond(cost); await flushPromises()
|
||||
expect(w.findAllComponents({ name: 'AppDialog' })[0]!.props('modelValue')).toBe(false)
|
||||
})
|
||||
it('unlocks a definite HTTP200 business rejection for correction with a fresh create key', async () => {
|
||||
vi.mocked(api.createTripCost).mockRejectedValueOnce(new ApiResponseError('业务拒绝', 'A0422', 200))
|
||||
const w = mount(); await flushPromises(); await button(w, '登记成本').trigger('click'); await flushPromises()
|
||||
w.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 12.5)
|
||||
await button(w, '保存').trigger('click'); await flushPromises()
|
||||
const first = vi.mocked(api.createTripCost).mock.calls[0]!
|
||||
expect(w.text()).not.toContain('正在核对上次登记结果')
|
||||
w.findComponent({ name: 'ElInputNumber' }).vm.$emit('update:modelValue', 10)
|
||||
await button(w, '保存').trigger('click'); await flushPromises()
|
||||
const second = vi.mocked(api.createTripCost).mock.calls[1]!
|
||||
expect(second[1]).not.toBe(first[1]); expect(second[2].amount).toBe(10)
|
||||
})
|
||||
it('reads the current version before editing and avoids writing unchanged contents', async () => {
|
||||
const w = mount(); await flushPromises(); await button(w, '更正').trigger('click'); await flushPromises()
|
||||
expect(api.listTripCostHistory).toHaveBeenCalledExactlyOnceWith('TR-ONE', 'TC-ONE', 1, 1)
|
||||
|
||||
Reference in New Issue
Block a user