Files
Mujoco_WASM/web_platform/src/app/components/MapViewportTools.test.tsx
T
chenlin 13e35be98b
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
feat(web-platform): release V0.9.3 全模块界面重构
2026-09-08 17:57:57 +08:00

110 lines
3.9 KiB
TypeScript

import { fireEvent, render, screen } from '@testing-library/react';
import { MapDraftStatusOverlay, MapViewportToolbar } from './MapViewportTools';
const noop = () => {};
describe('MapViewportToolbar', () => {
it('统一联动变换、吸附与贴地检测命令', () => {
const onModeChange = vi.fn();
const onSnappingChange = vi.fn();
const onPlacementModeChange = vi.fn();
const onAlignToSurface = vi.fn();
render(
<MapViewportToolbar
visible
interactionActive
mode="translate"
snapping
placementMode="auto_ground"
hasSelectedObject
allowScale
loading={false}
onActivate={noop}
onModeChange={onModeChange}
onSnappingChange={onSnappingChange}
onPlacementModeChange={onPlacementModeChange}
onAlignToSurface={onAlignToSurface}
/>,
);
fireEvent.click(screen.getByRole('button', { name: '旋转工具 E' }));
fireEvent.click(screen.getByRole('button', { name: '网格吸附' }));
fireEvent.change(screen.getByLabelText('贴地检测模式'), {
target: { value: 'gravity' },
});
fireEvent.click(screen.getByRole('button', { name: '立即贴合承载面' }));
expect(onModeChange).toHaveBeenCalledWith('rotate');
expect(onSnappingChange).toHaveBeenCalledWith(false);
expect(onPlacementModeChange).toHaveBeenCalledWith('gravity');
expect(onAlignToSurface).toHaveBeenCalledOnce();
});
it('参数地形或未选中对象时不提供缩放与贴合动作', () => {
render(
<MapViewportToolbar
visible
interactionActive
mode="translate"
snapping={false}
placementMode="auto_ground"
hasSelectedObject={false}
allowScale={false}
loading={false}
onActivate={noop}
onModeChange={noop}
onSnappingChange={noop}
onPlacementModeChange={noop}
onAlignToSurface={noop}
/>,
);
expect(screen.queryByRole('button', { name: '缩放工具 R' })).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: '立即贴合承载面' })).toBeDisabled();
});
});
describe('MapDraftStatusOverlay', () => {
it('提交中与失败摘要不能隐藏,失败保留重试和放弃入口', () => {
const props = { visible: true, changeCount: 2, onCommit: noop, onDiscard: noop };
const { rerender } = render(<MapDraftStatusOverlay {...props} loading />);
expect(screen.getByRole('status')).toHaveTextContent('正在应用草稿');
expect(screen.getByRole('button', { name: '提交地图草稿' })).toBeDisabled();
rerender(<MapDraftStatusOverlay {...props} loading={false} error="编译失败,草稿已保留" />);
expect(screen.getByRole('status')).toHaveTextContent('应用失败');
expect(screen.getByRole('status')).toHaveTextContent('编译失败,草稿已保留');
expect(screen.getByRole('button', { name: '提交地图草稿' })).toBeEnabled();
expect(screen.getByRole('button', { name: '丢弃地图草稿' })).toBeEnabled();
});
it('显示未保存数量并提供提交与丢弃入口', () => {
const onCommit = vi.fn();
const onDiscard = vi.fn();
render(
<MapDraftStatusOverlay
visible
changeCount={3}
loading={false}
onCommit={onCommit}
onDiscard={onDiscard}
/>,
);
expect(screen.getByText('3 项未保存改动')).toBeVisible();
fireEvent.click(screen.getByRole('button', { name: '提交地图草稿' }));
fireEvent.click(screen.getByRole('button', { name: '丢弃地图草稿' }));
expect(onCommit).toHaveBeenCalledOnce();
expect(onDiscard).toHaveBeenCalledOnce();
});
it('无草稿时不占位', () => {
render(
<MapDraftStatusOverlay
visible
changeCount={0}
loading={false}
onCommit={noop}
onDiscard={noop}
/>,
);
expect(screen.queryByLabelText('地图草稿状态')).not.toBeInTheDocument();
});
});