import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import FileSelector from '../../src/components/FileSelector'; // Mock API客户端 vi.mock('../../src/api/fileClient', () => ({ fileClient: { $get: vi.fn(), ':id': { $get: vi.fn(), }, }, })); // Mock 文件上传组件 vi.mock('../../src/components/MinioUploader', () => ({ default: () =>
MinioUploader
, })); describe('FileSelector', () => { let queryClient: QueryClient; beforeEach(() => { queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false }, }, }); vi.clearAllMocks(); }); const renderWithQueryClient = (component: React.ReactElement) => { return render( {component} ); }; const mockFiles = [ { id: 1, name: 'test-image.jpg', type: 'image/jpeg', size: 1024, fullUrl: 'http://example.com/test-image.jpg', uploadTime: '2024-01-01T00:00:00Z', }, { id: 2, name: 'test-document.pdf', type: 'application/pdf', size: 2048, fullUrl: 'http://example.com/test-document.pdf', uploadTime: '2024-01-01T00:00:00Z', }, ]; it('应该渲染文件选择器', () => { renderWithQueryClient( {}} /> ); expect(screen.getByText('选择文件')).toBeInTheDocument(); }); it('应该打开选择对话框', async () => { const { fileClient } = require('../../src/api/fileClient'); fileClient.$get.mockResolvedValue({ ok: true, json: async () => ({ data: mockFiles, pagination: { current: 1, pageSize: 50, total: 2 } }) }); renderWithQueryClient( {}} /> ); const selectButton = screen.getByText('选择文件'); fireEvent.click(selectButton); await waitFor(() => { expect(screen.getByText('选择文件')).toBeInTheDocument(); expect(screen.getByText('上传新文件或从已有文件中选择')).toBeInTheDocument(); }); }); it('应该显示已选文件预览', async () => { const { fileClient } = require('../../src/api/fileClient'); fileClient[':id'].$get.mockResolvedValue({ ok: true, json: async () => mockFiles[0] }); renderWithQueryClient( {}} showPreview={true} /> ); await waitFor(() => { expect(screen.getByText('更换文件')).toBeInTheDocument(); }); }); it('应该支持多选模式', async () => { const { fileClient } = require('../../src/api/fileClient'); fileClient.$get.mockResolvedValue({ ok: true, json: async () => ({ data: mockFiles, pagination: { current: 1, pageSize: 50, total: 2 } }) }); const onChange = vi.fn(); renderWithQueryClient( ); await waitFor(() => { expect(screen.getByText('已选择 2 个文件')).toBeInTheDocument(); }); }); it('应该过滤文件类型', async () => { const { fileClient } = require('../../src/api/fileClient'); fileClient.$get.mockResolvedValue({ ok: true, json: async () => ({ data: mockFiles, pagination: { current: 1, pageSize: 50, total: 2 } }) }); renderWithQueryClient( {}} filterType="image" /> ); const selectButton = screen.getByText('选择文件'); fireEvent.click(selectButton); await waitFor(() => { expect(fileClient.$get).toHaveBeenCalledWith({ query: { page: 1, pageSize: 50, keyword: 'image' } }); }); }); it('应该处理文件选择确认', async () => { const { fileClient } = require('../../src/api/fileClient'); fileClient.$get.mockResolvedValue({ ok: true, json: async () => ({ data: mockFiles, pagination: { current: 1, pageSize: 50, total: 2 } }) }); const onChange = vi.fn(); renderWithQueryClient( ); const selectButton = screen.getByText('选择文件'); fireEvent.click(selectButton); await waitFor(() => { const fileItems = screen.getAllByText('test-image.jpg'); fireEvent.click(fileItems[0]); }); const confirmButton = screen.getByText('确认选择'); fireEvent.click(confirmButton); expect(onChange).toHaveBeenCalledWith(1); }); });