| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- import { describe, it, expect, vi, beforeEach } from 'vitest';
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
- import { PhotoUploadField } from '../../src/components/PhotoUploadField';
- import { toast } from 'sonner';
- // Mock toast
- vi.mock('sonner', () => ({
- toast: {
- warning: vi.fn(),
- success: vi.fn(),
- error: vi.fn(),
- },
- }));
- // Mock FileSelector
- vi.mock('@d8d/file-management-ui/components', () => ({
- FileSelector: ({ value, onChange, accept, filterType, placeholder, showPreview, previewSize }: any) => (
- <div data-testid="file-selector">
- <button
- data-testid="file-selector-button"
- onClick={() => onChange?.(123)}
- >
- {placeholder || '选择文件'}
- </button>
- <div data-testid="file-selector-accept">{accept}</div>
- <div data-testid="file-selector-filter-type">{filterType}</div>
- <div data-testid="file-selector-preview">{showPreview ? 'show' : 'hide'}</div>
- <div data-testid="file-selector-preview-size">{previewSize}</div>
- </div>
- ),
- }));
- describe('PhotoUploadField', () => {
- beforeEach(() => {
- vi.clearAllMocks();
- });
- const defaultProps = {
- value: [],
- onChange: vi.fn(),
- photoTypes: ['身份证照片', '残疾证照片', '个人照片', '其他照片'],
- };
- it('应该正确渲染组件', () => {
- render(<PhotoUploadField {...defaultProps} />);
- expect(screen.getByText('照片上传')).toBeInTheDocument();
- expect(screen.getByTestId('add-photo-button')).toBeInTheDocument();
- expect(screen.getByText('暂无照片')).toBeInTheDocument();
- expect(screen.getByText('点击"添加照片"按钮上传照片')).toBeInTheDocument();
- });
- it('应该添加照片', () => {
- render(<PhotoUploadField {...defaultProps} />);
- const addButton = screen.getByTestId('add-photo-button');
- fireEvent.click(addButton);
- expect(defaultProps.onChange).toHaveBeenCalledWith([
- expect.objectContaining({
- photoType: '身份证照片',
- fileId: null,
- canDownload: 0,
- })
- ]);
- });
- it('应该添加多张照片(无限制)', () => {
- render(<PhotoUploadField {...defaultProps} />);
- const addButton = screen.getByTestId('add-photo-button');
- // 添加5张照片(原来限制是5张)
- for (let i = 0; i < 5; i++) {
- fireEvent.click(addButton);
- }
- // 应该可以添加超过5张照片
- fireEvent.click(addButton);
- expect(defaultProps.onChange).toHaveBeenCalledTimes(6);
- });
- it('应该支持自定义最大照片数量', () => {
- render(<PhotoUploadField {...defaultProps} maxPhotos={3} />);
- const addButton = screen.getByTestId('add-photo-button');
- // 添加3张照片
- for (let i = 0; i < 3; i++) {
- fireEvent.click(addButton);
- }
- // 尝试添加第4张照片应该显示警告
- fireEvent.click(addButton);
- expect(toast.warning).toHaveBeenCalledWith('最多只能上传 3 张照片');
- });
- it('应该移除照片', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- tempId: 'temp-1',
- },
- {
- photoType: '残疾证照片',
- fileId: 456,
- canDownload: 0,
- tempId: 'temp-2',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} />);
- // 找到并点击删除按钮
- const deleteButtons = screen.getAllByRole('button', { name: '' });
- const firstDeleteButton = deleteButtons.find(button =>
- button.innerHTML.includes('Trash2')
- );
- if (firstDeleteButton) {
- fireEvent.click(firstDeleteButton);
- }
- expect(defaultProps.onChange).toHaveBeenCalledWith([
- expect.objectContaining({
- photoType: '残疾证照片',
- fileId: 456,
- canDownload: 0,
- })
- ]);
- });
- it('应该更新照片类型', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- tempId: 'temp-1',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} />);
- // 找到选择器并更改值
- const selectTrigger = screen.getByText('身份证照片');
- fireEvent.click(selectTrigger);
- // 选择新类型
- const newTypeOption = screen.getByText('残疾证照片');
- fireEvent.click(newTypeOption);
- expect(defaultProps.onChange).toHaveBeenCalledWith([
- expect.objectContaining({
- photoType: '残疾证照片',
- fileId: 123,
- canDownload: 1,
- })
- ]);
- });
- it('应该更新文件ID', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: null,
- canDownload: 1,
- tempId: 'temp-1',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} />);
- // 点击文件选择器按钮
- const fileSelectorButton = screen.getByTestId('file-selector-button');
- fireEvent.click(fileSelectorButton);
- expect(defaultProps.onChange).toHaveBeenCalledWith([
- expect.objectContaining({
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- })
- ]);
- });
- it('应该更新下载权限', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 0,
- tempId: 'temp-1',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} />);
- // 找到开关并切换
- const switchElement = screen.getByRole('switch');
- fireEvent.click(switchElement);
- expect(defaultProps.onChange).toHaveBeenCalledWith([
- expect.objectContaining({
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- })
- ]);
- });
- it('应该显示正确的文件格式和大小限制提示', () => {
- render(<PhotoUploadField {...defaultProps} />);
- expect(screen.getByText('支持的照片格式:JPG、JPEG、PNG、GIF、BMP、WebP等常见图片格式')).toBeInTheDocument();
- expect(screen.getByText('文件大小限制:无限制(建议不超过500MB)')).toBeInTheDocument();
- });
- it('应该使用正确的文件选择器配置', () => {
- render(<PhotoUploadField {...defaultProps} />);
- // 添加一张照片以显示文件选择器
- const addButton = screen.getByTestId('add-photo-button');
- fireEvent.click(addButton);
- expect(screen.getByTestId('file-selector-accept')).toHaveTextContent('image/*,.jpg,.jpeg,.png,.gif,.bmp,.webp');
- expect(screen.getByTestId('file-selector-filter-type')).toHaveTextContent('all');
- expect(screen.getByTestId('file-selector-preview')).toHaveTextContent('show');
- expect(screen.getByTestId('file-selector-preview-size')).toHaveTextContent('medium');
- });
- it('应该显示照片类型标签(无星号)', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- tempId: 'temp-1',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} />);
- // 检查照片类型标签没有星号
- const photoTypeLabel = screen.getByText('照片类型');
- expect(photoTypeLabel).toBeInTheDocument();
- expect(photoTypeLabel.innerHTML).not.toContain('*');
- });
- it('应该显示照片文件标签(无星号)', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- tempId: 'temp-1',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} />);
- // 检查照片文件标签没有星号
- const photoFileLabel = screen.getByText('照片文件');
- expect(photoFileLabel).toBeInTheDocument();
- expect(photoFileLabel.innerHTML).not.toContain('*');
- });
- it('应该显示添加更多照片按钮(无数量限制时)', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- tempId: 'temp-1',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} />);
- expect(screen.getByText('添加更多照片')).toBeInTheDocument();
- });
- it('应该显示添加更多照片按钮(有数量限制时)', () => {
- const initialValue = [
- {
- photoType: '身份证照片',
- fileId: 123,
- canDownload: 1,
- tempId: 'temp-1',
- },
- ];
- render(<PhotoUploadField {...defaultProps} value={initialValue} maxPhotos={5} />);
- expect(screen.getByText('添加更多照片(1/5)')).toBeInTheDocument();
- });
- });
|