/* eslint-disable @next/next/no-img-element, jsx-a11y/alt-text */
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import BatchFileList from './BatchFileList'
import { BatchVideoList } from './SpecialBatchUploadUI'
function createPngFile(name: string, width = 1920, height = 1080) {
const bytes = new Uint8Array(24)
bytes.set([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])
const view = new DataView(bytes.buffer)
view.setUint32(16, width)
view.setUint32(20, height)
return new File([bytes], name, { type: 'image/png' })
}
jest.mock('next/image', () => ({
__esModule: true,
default: (props: any) => {
const { fill, unoptimized, sizes, ...rest } = props
return
},
}))
test('无法从视频文件名确认 SPU 时直接显示可恢复的填写提示', () => {
render(
,
)
expect(screen.getByText(/未识别到 SPU,请填写/)).toBeInTheDocument()
const input = screen.getByRole('textbox', { name: 'SPU型号 *' })
expect(input).toHaveAttribute('aria-invalid', 'true')
expect(input).toHaveAccessibleDescription(/文件名不是完整、合规的 SPU/)
})
test('用户输入只自动转大写,非法字符保留并显示错误', () => {
const onUpdateProductModel = jest.fn()
render(
,
)
const input = screen.getByRole('textbox', { name: /SPU型号/ })
expect(input).toHaveValue('DF-A3DZ0008 中文')
expect(input).toHaveAttribute('aria-invalid', 'true')
expect(input).toHaveAccessibleDescription(/只能使用字母、数字/)
fireEvent.change(input, { target: { value: 'df-a3dz0008 中文' } })
expect(onUpdateProductModel).toHaveBeenCalledWith(0, 'df-a3dz0008 中文')
})
test('批量视频的每个文件都提供独立的选填预览图入口', async () => {
const onUpdatePreviewImage = jest.fn().mockResolvedValue(undefined)
render(
,
)
expect(screen.getByText('视频预览图')).toBeInTheDocument()
expect(screen.getByText('(选填)')).toBeInTheDocument()
expect(screen.queryByText('预览图片 *')).not.toBeInTheDocument()
const input = screen.getByLabelText(/视频预览图/) as HTMLInputElement
const cover = createPngFile('SPU001-cover.png')
fireEvent.change(input, { target: { files: [cover] } })
await waitFor(() => expect(onUpdatePreviewImage).toHaveBeenCalledWith(0, cover))
})
test('淘系-逛逛视频专用批量列表也提供独立的选填预览图入口', async () => {
const onUpdatePreviewImage = jest.fn().mockResolvedValue(undefined)
render(
,
)
expect(screen.getByText('视频预览图')).toBeInTheDocument()
expect(screen.getByText('(选填)')).toBeInTheDocument()
const input = screen.getByLabelText(/视频预览图/) as HTMLInputElement
const cover = createPngFile('SPU002-cover.png')
fireEvent.change(input, { target: { files: [cover] } })
await waitFor(() => expect(onUpdatePreviewImage).toHaveBeenCalledWith(0, cover))
})
test('通用和专用批量入口都在创建预览前拒绝超大像素图片', async () => {
const hugeCover = createPngFile('huge-cover.png', 10_000, 7_000)
const generalUpdate = jest.fn()
const generalError = jest.fn()
const generalView = render(
,
)
fireEvent.change(screen.getByLabelText(/视频预览图/), {
target: { files: [hugeCover] },
})
await waitFor(() => expect(generalError).toHaveBeenLastCalledWith(
expect.stringContaining('像素总量超过 60,000,000'),
))
expect(generalUpdate).not.toHaveBeenCalled()
generalView.unmount()
const specialUpdate = jest.fn()
const specialError = jest.fn()
render(
,
)
fireEvent.change(screen.getByLabelText(/视频预览图/), {
target: { files: [hugeCover] },
})
await waitFor(() => expect(specialError).toHaveBeenLastCalledWith(
expect.stringContaining('像素总量超过 60,000,000'),
))
expect(specialUpdate).not.toHaveBeenCalled()
})
test('上传期间锁定通用批量视频的元数据和删除操作', () => {
render(
,
)
expect(screen.getByRole('textbox', { name: 'SPU型号 *' })).toBeDisabled()
expect(screen.getByRole('button', { name: '删除' })).toBeDisabled()
expect(screen.getByRole('button', { name: '退出批量模式' })).toBeDisabled()
expect(screen.getByLabelText(/视频预览图/)).toBeDisabled()
})
test('上传期间锁定专用批量视频的 SPU、品类和删除操作', () => {
render(
,
)
expect(screen.getByPlaceholderText('SPU型号')).toBeDisabled()
expect(screen.getByRole('combobox', { name: '品类(可选)' })).toBeDisabled()
expect(screen.getByRole('button', { name: '删除' })).toBeDisabled()
expect(screen.getByLabelText(/视频预览图/)).toBeDisabled()
})