Files
admin-web/src/modules/overseas-warehouse/pages/CustomerVisitsView.test.ts
T

77 lines
3.9 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 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()
})
})