e6b3199490
之前遇到几次弹窗的样式不生效,bug 现在在画布agent的删除对话弹窗又出现了, 这个pr把类似的修改集中到最下层的UnifiedModal,适用于所有的modal, 一些特殊的modal有特殊处理. 画布agent的删除对话弹窗  --------- Co-authored-by: 段舒康 <kdletters@qq.com> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/122 Reviewed-by: 段舒康 <kdletters@qq.com> Co-authored-by: 王德宇 <kvtodev@outlook.com> Co-committed-by: 王德宇 <kvtodev@outlook.com>
183 lines
4.7 KiB
TypeScript
183 lines
4.7 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
import type React from 'react';
|
|
import { expect, test, vi } from 'vitest';
|
|
|
|
import { PlatformImagePreviewModal } from './PlatformImagePreviewModal';
|
|
import { clampPlatformImagePreviewTransform } from './platformImagePreviewModel';
|
|
|
|
vi.mock('../ResolvedAssetImage', () => ({
|
|
ResolvedAssetImage: ({
|
|
src,
|
|
alt,
|
|
className,
|
|
style,
|
|
draggable,
|
|
onLoad,
|
|
}: {
|
|
src?: string | null;
|
|
alt?: string;
|
|
className?: string;
|
|
style?: React.CSSProperties;
|
|
draggable?: boolean;
|
|
onLoad?: React.ReactEventHandler<HTMLImageElement>;
|
|
}) =>
|
|
src ? (
|
|
<img
|
|
src={src}
|
|
alt={alt}
|
|
className={className}
|
|
style={style}
|
|
draggable={draggable}
|
|
onLoad={onLoad}
|
|
/>
|
|
) : null,
|
|
}));
|
|
|
|
test('clamps full-screen image preview zoom and drag within image bounds', () => {
|
|
expect(
|
|
clampPlatformImagePreviewTransform(
|
|
{
|
|
scale: 8,
|
|
offsetX: 999,
|
|
offsetY: -999,
|
|
},
|
|
{ width: 400, height: 800 },
|
|
{ width: 400, height: 400 },
|
|
),
|
|
).toEqual({
|
|
scale: 4,
|
|
offsetX: 600,
|
|
offsetY: -400,
|
|
});
|
|
|
|
expect(
|
|
clampPlatformImagePreviewTransform(
|
|
{
|
|
scale: 4,
|
|
offsetX: -999,
|
|
offsetY: 999,
|
|
},
|
|
{ width: 400, height: 800 },
|
|
{ width: 400, height: 400 },
|
|
),
|
|
).toEqual({
|
|
scale: 4,
|
|
offsetX: -600,
|
|
offsetY: 400,
|
|
});
|
|
|
|
expect(
|
|
clampPlatformImagePreviewTransform(
|
|
{
|
|
scale: 0.25,
|
|
offsetX: 80,
|
|
offsetY: 80,
|
|
},
|
|
{ width: 400, height: 800 },
|
|
{ width: 400, height: 400 },
|
|
),
|
|
).toEqual({
|
|
scale: 1,
|
|
offsetX: 0,
|
|
offsetY: 0,
|
|
});
|
|
});
|
|
|
|
test('renders full-screen image preview with zoom controls and dark backdrop', () => {
|
|
render(
|
|
<PlatformImagePreviewModal
|
|
open
|
|
title="查看关卡图片"
|
|
imageSrc="/generated-puzzle-assets/session/level/image.png"
|
|
imageAlt="拼图关卡图"
|
|
closeLabel="关闭关卡图片预览"
|
|
onClose={() => {}}
|
|
/>,
|
|
);
|
|
|
|
const dialog = screen.getByRole('dialog', { name: '查看关卡图片' });
|
|
expect(dialog.className).toContain('platform-image-preview-modal');
|
|
expect(dialog.className).toContain('bg-black');
|
|
expect(
|
|
dialog.parentElement?.className.includes('!bg-black'),
|
|
).toBe(true);
|
|
expect(dialog.parentElement?.className).not.toContain('platform-theme--');
|
|
expect(screen.getByRole('button', { name: '放大图片' })).toBeTruthy();
|
|
expect(screen.getByRole('button', { name: '缩小图片' })).toBeTruthy();
|
|
expect(screen.getByRole('button', { name: '重置图片缩放' })).toBeTruthy();
|
|
expect(screen.getByAltText('拼图关卡图').getAttribute('draggable')).toBe(
|
|
'false',
|
|
);
|
|
});
|
|
|
|
test('zooms to at most four times and clamps dragged image position', async () => {
|
|
render(
|
|
<PlatformImagePreviewModal
|
|
open
|
|
title="查看关卡图片"
|
|
imageSrc="/generated-puzzle-assets/session/level/image.png"
|
|
imageAlt="拼图关卡图"
|
|
closeLabel="关闭关卡图片预览"
|
|
onClose={() => {}}
|
|
/>,
|
|
);
|
|
|
|
const stage = screen.getByTestId('platform-image-preview-stage');
|
|
Object.defineProperty(stage, 'getBoundingClientRect', {
|
|
configurable: true,
|
|
value: () => ({
|
|
width: 400,
|
|
height: 800,
|
|
top: 0,
|
|
right: 400,
|
|
bottom: 800,
|
|
left: 0,
|
|
x: 0,
|
|
y: 0,
|
|
toJSON: () => ({}),
|
|
}),
|
|
});
|
|
|
|
const image = screen.getByAltText('拼图关卡图') as HTMLImageElement;
|
|
Object.defineProperties(image, {
|
|
naturalWidth: { configurable: true, value: 400 },
|
|
naturalHeight: { configurable: true, value: 400 },
|
|
});
|
|
|
|
await act(async () => {
|
|
window.dispatchEvent(new Event('resize'));
|
|
fireEvent.load(image);
|
|
});
|
|
|
|
await waitFor(() => {
|
|
expect(image.style.width).toBe('400px');
|
|
expect(image.style.height).toBe('400px');
|
|
});
|
|
|
|
for (let index = 0; index < 8; index += 1) {
|
|
fireEvent.click(screen.getByRole('button', { name: '放大图片' }));
|
|
}
|
|
|
|
await waitFor(() => {
|
|
expect(image.style.transform).toContain(
|
|
'translate3d(0px, 0px, 0) scale(4)',
|
|
);
|
|
});
|
|
|
|
fireEvent.pointerDown(stage, { pointerId: 1, clientX: 200, clientY: 400 });
|
|
fireEvent.pointerMove(stage, { pointerId: 1, clientX: 1200, clientY: 1200 });
|
|
fireEvent.pointerUp(stage, { pointerId: 1, clientX: 1200, clientY: 1200 });
|
|
|
|
await waitFor(() => {
|
|
const offsetMatch = image.style.transform.match(
|
|
/translate3d\((-?\d+)px, (-?\d+)px, 0\) scale\(4\)/u,
|
|
);
|
|
|
|
expect(offsetMatch).not.toBeNull();
|
|
expect(Math.abs(Number(offsetMatch?.[1]))).toBe(600);
|
|
expect(Math.abs(Number(offsetMatch?.[2]))).toBe(400);
|
|
});
|
|
});
|