/* @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;
}) =>
,
}));
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');
});