117 lines
3.7 KiB
JavaScript
117 lines
3.7 KiB
JavaScript
/**
|
|
* FmsSelect 远程查找选择器测试。
|
|
* 覆盖契约:展开即加载首页、选中抛出 id/label/整行 record、
|
|
* 键入按 labelKey 防抖远程 LIKE 搜索、当前选中项不在结果中时回显补入列表首。
|
|
*/
|
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
import { mount, flushPromises } from '@vue/test-utils'
|
|
import { nextTick } from 'vue'
|
|
import FmsSelect from '@/components/fms-select/FmsSelect.vue'
|
|
import { pageDataApi } from '@/services/api'
|
|
|
|
vi.mock('@/services/api', () => ({
|
|
pageDataApi: vi.fn(),
|
|
}))
|
|
|
|
/** 让 pageDataApi 返回给定行 */
|
|
function mockRows(rows, total = rows.length) {
|
|
pageDataApi.mockResolvedValue({ data: { rows, total } })
|
|
}
|
|
|
|
beforeEach(() => {
|
|
pageDataApi.mockReset()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers()
|
|
// 清空 Teleport 到 body 的下拉浮层残留;replaceChildren 不解析 markup,比 innerHTML='' 更安全
|
|
document.body.replaceChildren()
|
|
})
|
|
|
|
describe('FmsSelect 远程查找', () => {
|
|
it('展开即加载首页并渲染选项', async () => {
|
|
mockRows([
|
|
{ b_id: '1', b_name: '甲' },
|
|
{ b_id: '2', b_name: '乙' },
|
|
])
|
|
const wrapper = mount(FmsSelect, {
|
|
props: { viewName: 'v_customer' },
|
|
attachTo: document.body,
|
|
})
|
|
|
|
await wrapper.find('.select-trigger').trigger('click')
|
|
await flushPromises()
|
|
await nextTick()
|
|
|
|
expect(pageDataApi).toHaveBeenCalledWith(
|
|
expect.objectContaining({ viewName: 'v_customer', pageNo: 1 }),
|
|
)
|
|
const options = document.body.querySelectorAll('.select-option')
|
|
expect(options.length).toBe(2)
|
|
expect(options[0].textContent).toContain('甲')
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('选中抛出 id / label / 整行 record', async () => {
|
|
mockRows([{ b_id: '1', b_name: '甲', extra: 'x' }])
|
|
const wrapper = mount(FmsSelect, {
|
|
props: { viewName: 'v_customer' },
|
|
attachTo: document.body,
|
|
})
|
|
|
|
await wrapper.find('.select-trigger').trigger('click')
|
|
await flushPromises()
|
|
await nextTick()
|
|
|
|
document.body.querySelector('.select-option').click()
|
|
await flushPromises()
|
|
await nextTick()
|
|
|
|
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['1'])
|
|
expect(wrapper.emitted('update:label')?.at(-1)).toEqual(['甲'])
|
|
expect(wrapper.emitted('change')?.at(-1)?.[0]).toEqual({ b_id: '1', b_name: '甲', extra: 'x' })
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('当前选中项不在结果中时回显到列表首', async () => {
|
|
mockRows([{ b_id: '2', b_name: '乙' }])
|
|
const wrapper = mount(FmsSelect, {
|
|
props: { viewName: 'v_customer', modelValue: '9', label: '既存客户' },
|
|
attachTo: document.body,
|
|
})
|
|
|
|
await wrapper.find('.select-trigger').trigger('click')
|
|
await flushPromises()
|
|
await nextTick()
|
|
|
|
const options = document.body.querySelectorAll('.select-option')
|
|
expect(options.length).toBe(2)
|
|
expect(options[0].textContent).toContain('既存客户')
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('键入按 labelKey 远程 LIKE 搜索(防抖)', async () => {
|
|
mockRows([])
|
|
const wrapper = mount(FmsSelect, {
|
|
props: { viewName: 'v_customer', searchDelay: 300 },
|
|
attachTo: document.body,
|
|
})
|
|
|
|
// 先展开:immediate('') 会拉一次全量,与后续搜索区分开
|
|
await wrapper.find('.select-trigger').trigger('click')
|
|
await flushPromises()
|
|
|
|
vi.useFakeTimers()
|
|
pageDataApi.mockClear()
|
|
await wrapper.find('.select-input').setValue('kw')
|
|
// 防抖窗口内不发请求
|
|
expect(pageDataApi).not.toHaveBeenCalled()
|
|
|
|
await vi.advanceTimersByTimeAsync(300)
|
|
expect(pageDataApi).toHaveBeenCalledWith(
|
|
expect.objectContaining({ searchCondition: "b_name LIKE '%kw%'" }),
|
|
)
|
|
wrapper.unmount()
|
|
})
|
|
})
|