115 lines
3.4 KiB
TypeScript
115 lines
3.4 KiB
TypeScript
import { fireEvent, render, screen } from '@testing-library/react'
|
||
|
||
import DetailImageSorter from '@/components/upload/DetailImageSorter'
|
||
|
||
const images = [
|
||
{
|
||
id: 'detail-1',
|
||
file: new File(['first'], '1.jpg', { type: 'image/jpeg' }),
|
||
preview: 'blob:first',
|
||
previewStatus: 'ready' as const,
|
||
sortOrder: 0,
|
||
},
|
||
{
|
||
id: 'detail-2',
|
||
file: new File(['second'], '2.jpg', { type: 'image/jpeg' }),
|
||
preview: 'blob:second',
|
||
previewStatus: 'ready' as const,
|
||
sortOrder: 1,
|
||
},
|
||
]
|
||
|
||
describe('DetailImageSorter', () => {
|
||
test('加载中和不可用详情图只显示占位,不渲染空 src', () => {
|
||
const { container } = render(
|
||
<DetailImageSorter
|
||
images={[
|
||
{
|
||
id: 'loading',
|
||
file: new File(['loading'], 'loading.jpg', { type: 'image/jpeg' }),
|
||
preview: '',
|
||
previewStatus: 'loading',
|
||
previewMessage: '正在生成缩略图',
|
||
sortOrder: 0,
|
||
},
|
||
{
|
||
id: 'unavailable',
|
||
file: new File(['unavailable'], 'unavailable.jpg', { type: 'image/jpeg' }),
|
||
preview: '',
|
||
previewStatus: 'unavailable',
|
||
previewMessage: '浏览器无法生成缩略图',
|
||
sortOrder: 1,
|
||
},
|
||
]}
|
||
onChange={jest.fn()}
|
||
onRemove={jest.fn()}
|
||
/>,
|
||
)
|
||
|
||
expect(screen.getAllByRole('img', { name: 'loading.jpg:正在生成缩略图' })).toHaveLength(2)
|
||
expect(screen.getAllByRole('img', { name: 'unavailable.jpg:预览不可用' })).toHaveLength(2)
|
||
expect(container.querySelector('img')).toBeNull()
|
||
expect(container.querySelector('img[src=""]')).toBeNull()
|
||
})
|
||
|
||
test('外部文件拖到已有详情图上时应继续交给外层上传区域处理', () => {
|
||
const onOuterDrop = jest.fn()
|
||
|
||
render(
|
||
<div onDrop={onOuterDrop}>
|
||
<DetailImageSorter images={images} onChange={jest.fn()} onRemove={jest.fn()} />
|
||
</div>,
|
||
)
|
||
|
||
const externalFile = new File(['new-detail'], '3.jpg', { type: 'image/jpeg' })
|
||
const thumbnail = screen.getByAltText('缩略图 1')
|
||
|
||
fireEvent.dragOver(thumbnail, {
|
||
dataTransfer: {
|
||
files: [externalFile],
|
||
types: ['Files'],
|
||
dropEffect: 'copy',
|
||
},
|
||
})
|
||
fireEvent.drop(thumbnail, {
|
||
dataTransfer: {
|
||
files: [externalFile],
|
||
types: ['Files'],
|
||
dropEffect: 'copy',
|
||
},
|
||
})
|
||
|
||
expect(onOuterDrop).toHaveBeenCalledTimes(1)
|
||
})
|
||
|
||
test('详情图内部拖拽仍应完成排序且不触发外层文件上传', () => {
|
||
const onChange = jest.fn()
|
||
const onOuterDrop = jest.fn()
|
||
|
||
render(
|
||
<div onDrop={onOuterDrop}>
|
||
<DetailImageSorter images={images} onChange={onChange} onRemove={jest.fn()} />
|
||
</div>,
|
||
)
|
||
|
||
const firstThumbnail = screen.getByAltText('缩略图 1')
|
||
const secondThumbnail = screen.getByAltText('缩略图 2')
|
||
const dataTransfer = {
|
||
files: [],
|
||
types: [],
|
||
effectAllowed: 'none',
|
||
dropEffect: 'none',
|
||
}
|
||
|
||
fireEvent.dragStart(firstThumbnail, { dataTransfer })
|
||
fireEvent.dragOver(secondThumbnail, { dataTransfer })
|
||
fireEvent.drop(secondThumbnail, { dataTransfer })
|
||
|
||
expect(onChange).toHaveBeenCalledWith([
|
||
expect.objectContaining({ id: 'detail-2', sortOrder: 0 }),
|
||
expect.objectContaining({ id: 'detail-1', sortOrder: 1 }),
|
||
])
|
||
expect(onOuterDrop).not.toHaveBeenCalled()
|
||
})
|
||
})
|