/* @vitest-environment jsdom */ import { fireEvent, render, screen } from '@testing-library/react'; import { expect, test, vi } from 'vitest'; import { PlatformUploadPreviewCard } from './PlatformUploadPreviewCard'; vi.mock('../ResolvedAssetImage', () => ({ ResolvedAssetImage: ({ src, alt, className, }: { src?: string | null; alt?: string; className?: string; }) => {alt}, })); test('renders uploaded image preview with shared chrome', () => { render( , ); const image = screen.getByRole('img', { name: '反馈凭证预览' }); const removeButton = screen.getByRole('button', { name: '移除上传凭证' }); expect(image.getAttribute('src')).toBe('data:image/png;base64,abc'); expect(image.className).toContain('object-cover'); expect(removeButton.getAttribute('type')).toBe('button'); expect(removeButton.className).toContain('bg-black/55'); }); test('calls remove handler from preview action', () => { const onRemove = vi.fn(); render( , ); fireEvent.click(screen.getByRole('button', { name: '移除图片' })); expect(onRemove).toHaveBeenCalledTimes(1); }); test('supports preview action with resolved asset image', () => { const onPreview = vi.fn(); render( , ); const previewButton = screen.getByRole('button', { name: '预览参考图 1' }); fireEvent.click(previewButton); expect(screen.getByRole('img', { name: '参考图' }).getAttribute('src')).toBe( '/generated/reference.png', ); expect(onPreview).toHaveBeenCalledTimes(1); }); test('can render preview-only cards without remove action', () => { render( , ); expect(screen.getByRole('img', { name: '上传图片预览' })).toBeTruthy(); expect(screen.queryByRole('button', { name: '移除图片' })).toBeNull(); }); test('supports captioned preview cards for reference images', () => { const onPreview = vi.fn(); render( , ); const previewButton = screen.getByRole('button', { name: '预览参考图 草莓', }); fireEvent.click(previewButton); const previewImage = previewButton.querySelector('img'); expect(screen.getByText('草莓').className).toContain('pr-9'); expect(previewImage?.parentElement?.className).toContain('ring-1'); expect(onPreview).toHaveBeenCalledTimes(1); }); test('supports inline selected upload preview rows', () => { const onRemove = vi.fn(); render( , ); const image = screen.getByRole('img', { name: '创作参考图' }); const row = image.closest('div')?.parentElement; const removeButton = screen.getByRole('button', { name: '移除参考图' }); expect(row?.className).toContain('flex items-center gap-3'); expect(row?.className).toContain('bg-white/68'); expect(row?.className).toContain('px-3'); expect(row?.className).toContain('py-2'); expect(row?.className).toContain('mt-3'); expect(screen.getByText('森林参考图.png').className).toContain('truncate'); expect(removeButton.className).toContain('platform-icon-button'); expect(removeButton.getAttribute('title')).toBe('移除参考图'); fireEvent.click(removeButton); expect(onRemove).toHaveBeenCalledTimes(1); }); test('supports editor dark inline selected upload preview rows', () => { render( , ); const image = screen.getByRole('img', { name: '封面参考图' }); const imageShell = image.parentElement; const row = imageShell?.parentElement; const caption = screen.getByText('已载入封面参考图'); const removeButton = screen.getByRole('button', { name: '移除封面参考图' }); expect(row?.className).toContain('border-white/10'); expect(row?.className).toContain('bg-black/25'); expect(imageShell?.className).toContain('bg-black/30'); expect(imageShell?.className).toContain('!w-24'); expect(caption.className).toContain('text-zinc-300'); expect(removeButton.className).toContain('bg-black/55'); }); test('keeps disabled remove action inert', () => { const onRemove = vi.fn(); render( , ); const removeButton = screen.getByRole('button', { name: '移除图片' }); fireEvent.click(removeButton); expect(removeButton).toHaveProperty('disabled', true); expect(removeButton.className).toContain('disabled:cursor-not-allowed'); expect(onRemove).not.toHaveBeenCalled(); }); test('supports local size, image and remove button classes', () => { render( , ); const image = screen.getByRole('img', { name: '上传图片预览' }); const removeButton = screen.getByRole('button', { name: '移除图片' }); expect(image.parentElement?.className).toContain('h-20'); expect(image.className).toContain('object-top'); expect(removeButton.className).toContain('right-2'); });