import ElementPlus from 'element-plus' import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils' import { afterEach, describe, expect, it, vi } from 'vitest' import BatchImportDialog, { type BatchImportResult } from './BatchImportDialog.vue' class ResizeObserverStub implements ResizeObserver { observe() {} unobserve() {} disconnect() {} } function button(label: string) { return [...document.body.querySelectorAll('button')].find((item) => item.textContent?.trim() === label) } async function chooseFile(file: File) { const input = document.body.querySelector('input[type="file"]')! Object.defineProperty(input, 'files', { configurable: true, value: [file] }) input.dispatchEvent(new Event('change', { bubbles: true })) await flushPromises() } enableAutoUnmount(afterEach) describe('BatchImportDialog', () => { afterEach(() => { document.body.innerHTML = '' vi.unstubAllGlobals() }) it('uses the shared two-step flow and submits a validated XLSX file', async () => { vi.stubGlobal('ResizeObserver', ResizeObserverStub) const result: BatchImportResult = { fileName: 'partners.xlsx', totalRows: 2, importedRows: 2, success: true, errors: [], } const importFile = vi.fn().mockResolvedValue(result) const wrapper = mount(BatchImportDialog, { attachTo: document.body, props: { modelValue: true, title: '批量导入往来单位', entityLabel: '往来单位', templateFileName: '往来单位导入模板-v1.xlsx', downloadTemplate: vi.fn(), importFile, }, global: { plugins: [ElementPlus] }, }) await flushPromises() expect(document.body.textContent).toContain('下载标准模板') expect(document.body.textContent).toContain('选择填写后的文件') expect(button('开始导入')?.hasAttribute('disabled')).toBe(true) const file = new File(['xlsx'], 'partners.xlsx', { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }) await chooseFile(file) expect(button('开始导入')?.hasAttribute('disabled')).toBe(false) button('开始导入')?.click() await flushPromises() expect(importFile).toHaveBeenCalledWith(file) expect(wrapper.emitted('success')?.[0]).toEqual([result]) expect(document.body.textContent).toContain('导入完成:成功新增 2 条往来单位') }) it('rejects files that do not use the XLSX template format', async () => { vi.stubGlobal('ResizeObserver', ResizeObserverStub) const importFile = vi.fn() mount(BatchImportDialog, { attachTo: document.body, props: { modelValue: true, title: '批量导入快递公司', entityLabel: '快递公司', templateFileName: '快递公司批量导入模板-v1.xlsx', downloadTemplate: vi.fn(), importFile, }, global: { plugins: [ElementPlus] }, }) await flushPromises() await chooseFile(new File(['csv'], 'companies.csv', { type: 'text/csv' })) expect(button('开始导入')?.hasAttribute('disabled')).toBe(true) expect(importFile).not.toHaveBeenCalled() }) })