Files
Genarrative/src/components/image-editor/ImageCanvasPanelDockView.test.tsx
kdletters d8b935317d 拆分编辑器前端画布视图
抽出素材栏、生成器、舞台工具栏和画布世界视图

补充各拆分视图的聚焦测试

更新 TRACKING.md 记录第三十四阶段验证
2026-06-17 17:48:12 +08:00

113 lines
4.2 KiB
TypeScript

/* @vitest-environment jsdom */
import { fireEvent, render, screen, within } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import type { StageMinimapModel } from './ImageCanvasInteractionModel';
import { ImageCanvasPanelDockView } from './ImageCanvasPanelDockView';
function renderPanelDock(
overrides: Partial<Parameters<typeof ImageCanvasPanelDockView>[0]> = {},
) {
const props: Parameters<typeof ImageCanvasPanelDockView>[0] = {
viewport: { x: 0, y: 0, scale: 1 },
canvasBackgroundColor: '#f8fafc',
canvasBackgroundHexValue: '#f8fafc',
canUndo: true,
canRedo: false,
isZoomMenuOpen: false,
isBackgroundSettingsOpen: false,
activeSidebarPanel: null,
isMinimapOpen: false,
minimapModel: null,
onFitLayers: vi.fn(),
onUndoCanvasChange: vi.fn(),
onRedoCanvasChange: vi.fn(),
onUpdateScaleFromCenter: vi.fn(),
onToggleZoomMenu: vi.fn(),
onCloseZoomMenu: vi.fn(),
onToggleBackgroundSettings: vi.fn(),
onApplyCanvasBackgroundColor: vi.fn(),
onCanvasBackgroundHexChange: vi.fn(),
onToggleSidebarPanel: vi.fn(),
onToggleMinimap: vi.fn(),
onMinimapPointerDown: vi.fn(),
...overrides,
};
render(<ImageCanvasPanelDockView {...props} />);
return props;
}
describe('ImageCanvasPanelDockView', () => {
it('renders panel dock actions and forwards common controls', () => {
const props = renderPanelDock({
activeSidebarPanel: 'assets',
isMinimapOpen: true,
minimapModel: {
bounds: { minX: 0, minY: 0, maxX: 100, maxY: 100 },
scale: 1,
layers: [],
viewport: { left: '10%', top: '12%', width: '20%', height: '24%' },
} satisfies StageMinimapModel,
});
const toolbar = screen.getByRole('toolbar', { name: '画布面板入口' });
expect(
within(toolbar).getByRole('button', { name: '打开素材' }).getAttribute(
'aria-pressed',
),
).toBe('true');
expect(
(
within(toolbar).getByRole('button', { name: '重做' }) as HTMLButtonElement
).disabled,
).toBe(true);
expect(screen.getByRole('button', { name: '画布小地图' })).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: '重置画布视图' }));
fireEvent.click(within(toolbar).getByRole('button', { name: '撤销' }));
fireEvent.click(within(toolbar).getByRole('button', { name: '打开图层' }));
fireEvent.click(within(toolbar).getByRole('button', { name: '切换小地图' }));
expect(props.onFitLayers).toHaveBeenCalledTimes(1);
expect(props.onUndoCanvasChange).toHaveBeenCalledTimes(1);
expect(props.onToggleSidebarPanel).toHaveBeenCalledWith('layers');
expect(props.onToggleMinimap).toHaveBeenCalledTimes(1);
});
it('renders zoom and background settings with callback wiring', () => {
const props = renderPanelDock({
isZoomMenuOpen: true,
isBackgroundSettingsOpen: true,
});
fireEvent.click(screen.getByRole('menuitem', { name: '缩放至50%' }));
fireEvent.click(screen.getByRole('menuitem', { name: '显示画布所有元素' }));
expect(props.onUpdateScaleFromCenter).toHaveBeenCalledWith(0.5);
expect(props.onFitLayers).toHaveBeenCalledTimes(1);
expect(props.onCloseZoomMenu).toHaveBeenCalledTimes(2);
const panel = screen.getByRole('dialog', { name: '画布背景设置' });
fireEvent.click(within(panel).getByRole('button', { name: '暖灰' }));
fireEvent.change(within(panel).getByLabelText('自定义画布背景色'), {
target: { value: '#ffffff' },
});
fireEvent.change(within(panel).getByLabelText('画布背景十六进制颜色'), {
target: { value: '#abc' },
});
fireEvent.click(within(panel).getByRole('button', { name: '恢复默认' }));
fireEvent.click(within(panel).getByRole('button', { name: '关闭画布背景设置' }));
expect(props.onApplyCanvasBackgroundColor).toHaveBeenCalledWith('#f3f0ea');
expect(props.onApplyCanvasBackgroundColor).toHaveBeenCalledWith('#ffffff');
expect(props.onCanvasBackgroundHexChange).toHaveBeenCalledWith('#abc');
expect(props.onApplyCanvasBackgroundColor).toHaveBeenCalledWith('#f8fafc');
expect(props.onToggleBackgroundSettings).toHaveBeenCalledTimes(1);
});
});