import { createEvent, fireEvent, render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import AIChatWidget from '@/components/AIChatWidget' jest.mock('next-auth/react', () => ({ useSession: () => ({ data: { user: { id: 'user-1', name: '测试用户', }, }, }), })) describe('AIChatWidget 图片拖拽', () => { beforeEach(() => { Object.defineProperty(URL, 'createObjectURL', { configurable: true, writable: true, value: jest.fn((file: File) => `blob:${file.name}`), }) Object.defineProperty(URL, 'revokeObjectURL', { configurable: true, writable: true, value: jest.fn(), }) }) test('经过内部元素不应关闭拖拽提示', async () => { const user = userEvent.setup() render() await user.click(screen.getByRole('button', { name: 'AI助手' })) const welcome = screen.getByText('👋 你好!我是AI助手') const dropZone = welcome.parentElement?.parentElement as HTMLDivElement Object.defineProperty(dropZone, 'getBoundingClientRect', { configurable: true, value: () => ({ left: 0, right: 400, top: 0, bottom: 600, }), }) fireEvent.dragOver(dropZone, { clientX: 100, clientY: 100, dataTransfer: { files: [], types: ['Files'], dropEffect: 'none' }, }) expect(screen.getByText('松开鼠标上传图片')).toBeInTheDocument() const internalDragLeave = createEvent.dragLeave(dropZone) Object.defineProperties(internalDragLeave, { clientX: { value: 120 }, clientY: { value: 120 }, relatedTarget: { value: dropZone.firstElementChild }, dataTransfer: { value: { files: [], types: ['Files'], dropEffect: 'copy' } }, }) fireEvent(dropZone, internalDragLeave) expect(screen.getByText('松开鼠标上传图片')).toBeInTheDocument() }) test('最多接收5张图片并明确提示被忽略数量', async () => { const user = userEvent.setup() render() await user.click(screen.getByRole('button', { name: 'AI助手' })) const welcome = screen.getByText('👋 你好!我是AI助手') const dropZone = welcome.parentElement?.parentElement as HTMLDivElement const images = Array.from({ length: 6 }, (_, index) => ( new File([`${index}`], `${index + 1}.png`, { type: 'image/png' }) )) fireEvent.drop(dropZone, { dataTransfer: { files: images, types: ['Files'], dropEffect: 'copy' }, }) expect(screen.getAllByAltText(/待发送图片/)).toHaveLength(5) expect(screen.getByRole('alert')).toHaveTextContent('最多只能选择 5 张图片,已忽略 1 张') expect(screen.getByRole('button', { name: '发送' })).toBeEnabled() }) })