This commit is contained in:
2026-10-21 16:12:24 +08:00
parent a9c0285e22
commit 215cb7c6d5
7 changed files with 245 additions and 104 deletions
@@ -39,17 +39,15 @@ describe('whole-dispatch four-tab detail', () => {
const wrapper = mount(DispatchDetailView, options); await flushPromises()
expect(wrapper.text()).toContain('已退回客服处理(车辆信息)')
expect(wrapper.text()).toContain('司机资料需要更正')
vi.mocked(getDispatch).mockResolvedValue(detail({ recordVersion: 2 }))
wrapper.getComponent({ name: 'DispatchWorkflowDialog' }).vm.$emit('saved'); await flushPromises()
expect(wrapper.text()).not.toContain('司机资料需要更正')
expect(wrapper.findComponent({ name: 'DispatchWorkflowDialog' }).exists()).toBe(false)
wrapper.unmount()
})
it('keeps cargo additions and removals out of the detail even when authorized', async () => {
it('keeps every write action out of the detail even when authorized', async () => {
can.mockReturnValue(true)
vi.mocked(getDispatch).mockResolvedValueOnce(detail({ actions: { EDIT: { allowed: true, blockCode: null, blockReason: null }, ADD_CARGO: { allowed: true, blockCode: null, blockReason: null }, REMOVE_CARGO: { allowed: true, blockCode: null, blockReason: null } } }))
const wrapper = mount(DispatchDetailView, options); await flushPromises()
const actions = wrapper.get('[aria-label="排车操作"]').findAll('button').map(button => button.text())
expect(actions).toContain('维护车辆信息')
const actions = wrapper.findAll('button').map(button => button.text())
expect(actions).not.toContain('维护车辆信息')
expect(actions).not.toContain('添加货物')
expect(actions).not.toContain('移除货物')
wrapper.unmount()
@@ -58,6 +56,7 @@ describe('whole-dispatch four-tab detail', () => {
vi.mocked(getDispatch).mockResolvedValueOnce({ ...detail(), taskType })
const wrapper = mount(DispatchDetailView, options); await flushPromises()
expect(wrapper.get('transport-execution-panel-stub').attributes('dispatchno')).toBe('PC/1')
expect(wrapper.getComponent({ name: 'TransportExecutionPanel' }).props('readonly')).toBe(true)
expect(wrapper.findAll('[role="tab"]')).toHaveLength(0)
expect(wrapper.find('[aria-label="排车操作"]').exists()).toBe(false); wrapper.unmount()
})
@@ -124,7 +123,7 @@ describe('whole-dispatch four-tab detail', () => {
const wrapper = mount(DispatchDetailView, options); await flushPromises()
expect(wrapper.text()).not.toContain('尚未安排派送'); expect(wrapper.findAll('button').some(button => button.text() === '确认发车')).toBe(false); wrapper.unmount()
})
it('keeps the allowed Admin action without presenting unrelated stage or PDA permission refusals as page warnings', async () => {
it('shows stage facts without execution actions or unrelated permission refusals', async () => {
can.mockReturnValue(true)
vi.mocked(getDispatch).mockResolvedValueOnce(detail({ stage: 'LOADING', actions: {
LOADING_COMPLETE: { allowed: true, blockCode: null, blockReason: null },
@@ -136,8 +135,8 @@ describe('whole-dispatch four-tab detail', () => {
expect(wrapper.text()).not.toContain('当前阶段或作业事实不满足操作条件')
expect(wrapper.text()).not.toContain('当前无此操作权限')
expect(wrapper.findAll('button').some(button => button.text() === '维护车辆信息')).toBe(false)
await wrapper.findAll('button').find(button => button.text() === '确认装车完成')!.trigger('click')
expect(wrapper.findComponent({ name: 'DispatchWorkflowDialog' }).props()).toMatchObject({ modelValue: true, dispatchNo: 'PC/1', action: 'LOADING_COMPLETE' })
expect(wrapper.findAll('button').some(button => button.text() === '确认装车完成')).toBe(false)
expect(wrapper.findComponent({ name: 'DispatchWorkflowDialog' }).exists()).toBe(false)
wrapper.unmount()
})
it('retains a real attachment A0404 failure and its request diagnostics in the vehicle tab', async () => {
@@ -161,45 +160,16 @@ describe('whole-dispatch four-tab detail', () => {
Object.assign(query, { fleetOfferNo: 'FO-1', fleetBookingNo: 'FB-2' }); const wrapper = mount(DispatchDetailView, options); await flushPromises(); await wrapper.get('button.density-back').trigger('click')
expect(push).toHaveBeenCalledWith({ name: 'overseas-master-data-capacity-offer-detail', params: { offerNo: 'FO-1' }, query: { inquiry: 'FB-2' } }); wrapper.unmount()
})
it.each(['saved', 'rejected'] as const)('refreshes detail actions after the workflow %s event and retains a real rejection after closure', async event => {
it('does not mount review or mutation workflows for an authorized administrator', async () => {
can.mockReturnValue(true)
vi.mocked(getDispatch).mockResolvedValueOnce(detail({ actions: { SUBMIT_REVIEW: { allowed: true, blockCode: null, blockReason: null } } }))
const allowed = { allowed: true, blockCode: null, blockReason: null }
vi.mocked(getDispatch).mockResolvedValueOnce(detail({ actions: { EDIT: allowed, CANCEL: allowed, SUBMIT_REVIEW: allowed, DISPATCH_REVIEW: allowed, LOADING_REVIEW: allowed } }))
const wrapper = mount(DispatchDetailView, options); await flushPromises()
await wrapper.findAll('button').find(button => button.text() === '提交调度审核')!.trigger('click')
vi.mocked(getDispatch).mockResolvedValueOnce(detail({ recordVersion: 1, actions: { SUBMIT_REVIEW: { allowed: false, blockCode: 'ALREADY_SUBMITTED', blockReason: '已提交' } } }))
const dialog = wrapper.getComponent({ name: 'DispatchWorkflowDialog' })
if (event === 'rejected') dialog.vm.$emit('rejected', { message: '本轮审核已经提交', code: 'A0409', requestId: 'detail-reject-request' })
else dialog.vm.$emit('saved')
dialog.vm.$emit('update:modelValue', false)
await flushPromises()
expect(getDispatch).toHaveBeenCalledTimes(2)
expect(wrapper.findAll('button').some(button => button.text() === '提交调度审核')).toBe(false)
expect(wrapper.findComponent({ name: 'DispatchWorkflowDialog' }).exists()).toBe(false)
expect(wrapper.find('[aria-label="排车操作"]').exists()).toBe(false)
expect(wrapper.findAll('input, textarea')).toHaveLength(0)
expect(wrapper.findAll('[role="tab"]')).toHaveLength(4)
if (event === 'rejected') {
expect(wrapper.text()).toContain('本轮审核已经提交')
expect(wrapper.text()).toContain('A0409')
expect(wrapper.text()).toContain('detail-reject-request')
}
expect(wrapper.text()).not.toContain('结果尚待核对')
wrapper.unmount()
})
it('retains a workflow rejection when the parent detail refresh also fails', async () => {
const wrapper = mount(DispatchDetailView, options); await flushPromises()
vi.mocked(getDispatch).mockRejectedValueOnce(new Error('detail read failed'))
wrapper.getComponent({ name: 'DispatchWorkflowDialog' }).vm.$emit('rejected', { message: '已提交,请刷新', code: 'A0409' })
await flushPromises()
expect(wrapper.text()).toContain('已提交,请刷新')
expect(wrapper.text()).toContain('A0409')
expect(wrapper.text()).toContain('排车详情加载失败')
wrapper.unmount()
})
it('clears an earlier input rejection after the corrected workflow succeeds', async () => {
const wrapper = mount(DispatchDetailView, options); await flushPromises()
const dialog = wrapper.getComponent({ name: 'DispatchWorkflowDialog' })
dialog.vm.$emit('rejected', { message: '请补齐本趟资料', code: 'A0400' }); await flushPromises()
expect(wrapper.text()).toContain('请补齐本趟资料')
dialog.vm.$emit('saved'); await flushPromises()
expect(wrapper.text()).not.toContain('请补齐本趟资料')
expect(getDispatch).toHaveBeenCalledTimes(1)
wrapper.unmount()
})
})