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()
})
})