81 lines
4.1 KiB
TypeScript
81 lines
4.1 KiB
TypeScript
import ElementPlus from 'element-plus'
|
|
import { flushPromises, mount } from '@vue/test-utils'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { getCustomerVisit, listCustomerVisits, saveCustomerVisit, uploadCustomerVisitAttachment } from '../api/customerVisits'
|
|
import CustomerVisitsView from './CustomerVisitsView.vue'
|
|
import { commonPhase5Stubs } from './phase5TestStubs'
|
|
|
|
const canPermission = vi.hoisted(() => vi.fn((_code: string) => false))
|
|
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: canPermission }) }))
|
|
vi.mock('../api/customerVisits', () => ({ listCustomerVisits: vi.fn(), getCustomerVisit: vi.fn(), saveCustomerVisit: vi.fn(), uploadCustomerVisitAttachment: vi.fn() }))
|
|
|
|
const visit = {
|
|
id: '9', customerId: '100', deliveryNo: 'DEL-1', deliveryCompletedAt: '2026-09-01T10:00:00',
|
|
status: 'PENDING' as const, visitCount: 0, attachments: [],
|
|
}
|
|
function mountView() { return mount(CustomerVisitsView, { global: { plugins: [ElementPlus], stubs: commonPhase5Stubs } }) }
|
|
|
|
describe('CustomerVisitsView permissions and visit material', () => {
|
|
beforeEach(() => {
|
|
canPermission.mockReset().mockReturnValue(false)
|
|
vi.mocked(listCustomerVisits).mockReset().mockResolvedValue({ records: [visit], current: 1, size: 10, total: 1, pages: 1, visitable: 1, pending: 1, completed: 0 })
|
|
vi.mocked(getCustomerVisit).mockReset().mockResolvedValue({
|
|
visit,
|
|
inboundOrders: [{ inboundOrderId: '7', inboundCode: 'IN-1', lastMileOrderId: '6', lastMileOrderNo: 'LM-1', packageCount: 2 }],
|
|
customerFeedback: '', remark: '',
|
|
})
|
|
vi.mocked(saveCustomerVisit).mockReset().mockResolvedValue({ visit, inboundOrders: [] })
|
|
vi.mocked(uploadCustomerVisitAttachment).mockReset().mockResolvedValue({ fileId: '8', fileName: 'visit.pdf', sizeBytes: 4 })
|
|
})
|
|
|
|
it('hides the visit action without edit permission', async () => {
|
|
const wrapper = mountView()
|
|
await flushPromises()
|
|
expect(wrapper.find('[data-testid="data-table"]').text()).not.toContain('回访')
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('validates and submits a customer-scoped visit', async () => {
|
|
canPermission.mockImplementation(code => code.endsWith(':edit'))
|
|
const wrapper = mountView()
|
|
await flushPromises()
|
|
await wrapper.findAll('button').find(button => button.text() === '回访')!.trigger('click')
|
|
await flushPromises()
|
|
expect(getCustomerVisit).toHaveBeenCalledWith('9', '100')
|
|
|
|
const dialog = wrapper.find('[data-dialog="客户回访"]')
|
|
await dialog.find('.dialog-confirm').trigger('click')
|
|
expect(saveCustomerVisit).not.toHaveBeenCalled()
|
|
await dialog.find('select').setValue('NORMAL')
|
|
const textareas = dialog.findAll('textarea')
|
|
await textareas[0].setValue(' 服务正常 ')
|
|
await textareas[1].setValue(' 后续关注 ')
|
|
await dialog.find('.dialog-confirm').trigger('click')
|
|
await flushPromises()
|
|
expect(saveCustomerVisit).toHaveBeenCalledWith('9', '100', {
|
|
selectedInboundOrderId: '7', visitResult: 'NORMAL', customerFeedback: '服务正常', remark: '后续关注', attachments: [],
|
|
})
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('uploads the selected attachment in the visit customer scope', async () => {
|
|
canPermission.mockImplementation(code => code.endsWith(':edit'))
|
|
const wrapper = mountView()
|
|
await flushPromises()
|
|
await wrapper.findAll('button').find(button => button.text() === '回访')!.trigger('click')
|
|
await flushPromises()
|
|
const input = wrapper.find('[data-dialog="客户回访"] input[type="file"]')
|
|
const inputClick = vi.spyOn(input.element as HTMLInputElement, 'click').mockImplementation(() => {})
|
|
await wrapper.findAll('button').find(button => button.text() === '选择文件')!.trigger('click')
|
|
expect(inputClick).toHaveBeenCalledOnce()
|
|
inputClick.mockRestore()
|
|
const file = new File(['data'], 'visit.pdf', { type: 'application/pdf' })
|
|
Object.defineProperty(input.element, 'files', { configurable: true, value: [file] })
|
|
await input.trigger('change')
|
|
await flushPromises()
|
|
expect(uploadCustomerVisitAttachment).toHaveBeenCalledWith('9', '100', file)
|
|
expect(wrapper.text()).toContain('visit.pdf')
|
|
wrapper.unmount()
|
|
})
|
|
})
|