/* @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[0]> = {}, ) { const props: Parameters[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(); 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); }); });