130 lines
4.8 KiB
TypeScript
130 lines
4.8 KiB
TypeScript
import { fireEvent, render, screen } from '@testing-library/react';
|
||
import { decodeMapLibraryDragPayload, MAP_LIBRARY_DRAG_MIME } from './editor/assetCatalog';
|
||
import { MapAssetLibrary } from './MapAssetLibrary';
|
||
|
||
const renderLibrary = (
|
||
onAdd: (type: string, placementMode: string) => void = () => {},
|
||
onSelectTerrain: (preset: string) => void = () => {},
|
||
) =>
|
||
render(
|
||
<MapAssetLibrary
|
||
disabled={false}
|
||
terrainSize={8}
|
||
onAdd={onAdd}
|
||
onSelectTerrain={onSelectTerrain}
|
||
/>,
|
||
);
|
||
|
||
describe('MapAssetLibrary', () => {
|
||
it('只负责地图包、物理原语和预设地形的放置入口', () => {
|
||
expect(decodeMapLibraryDragPayload('not-json')).toBeNull();
|
||
expect(decodeMapLibraryDragPayload('{"kind":"terrain","preset":"unknown"}')).toBeNull();
|
||
renderLibrary();
|
||
const library = screen.getByLabelText('地图资产库');
|
||
expect(library).toHaveTextContent('场景资产库');
|
||
expect(library).toHaveTextContent('物理几何原语');
|
||
expect(library).toHaveTextContent('预设地形');
|
||
expect(library).not.toHaveTextContent('已放置地图');
|
||
});
|
||
|
||
it('地图包使用与资产卡片一致的添加和拖放入口', () => {
|
||
const values = new Map<string, string>();
|
||
const onAddProjectMap = vi.fn();
|
||
const dataTransfer = {
|
||
effectAllowed: 'none',
|
||
setData: (type: string, value: string) => values.set(type, value),
|
||
} as unknown as DataTransfer;
|
||
render(
|
||
<MapAssetLibrary
|
||
disabled={false}
|
||
terrainSize={8}
|
||
maps={[
|
||
{
|
||
descriptorPath: 'maps/warehouse/map.json',
|
||
schemaVersion: 1,
|
||
id: 'warehouse',
|
||
name: '仓库',
|
||
spawnPoints: [],
|
||
},
|
||
]}
|
||
onAdd={() => {}}
|
||
onAddProjectMap={onAddProjectMap}
|
||
onSelectTerrain={() => {}}
|
||
/>,
|
||
);
|
||
const source = document.querySelector('[data-project-map="maps/warehouse/map.json"]')!;
|
||
fireEvent.dragStart(source, { dataTransfer });
|
||
fireEvent.click(screen.getByRole('button', { name: '放置工程地图 仓库' }));
|
||
expect(decodeMapLibraryDragPayload(values.get(MAP_LIBRARY_DRAG_MIME) ?? '')).toEqual({
|
||
kind: 'project',
|
||
descriptorPath: 'maps/warehouse/map.json',
|
||
});
|
||
expect(onAddProjectMap).toHaveBeenCalledWith('maps/warehouse/map.json');
|
||
});
|
||
|
||
it('按所选放置方式添加物理几何原语', () => {
|
||
const onAdd = vi.fn();
|
||
renderLibrary(onAdd);
|
||
fireEvent.change(screen.getByLabelText('新增资产放置方式'), {
|
||
target: { value: 'gravity' },
|
||
});
|
||
fireEvent.click(screen.getByRole('button', { name: '添加基础方盒' }));
|
||
expect(onAdd).toHaveBeenCalledWith('box', 'gravity');
|
||
});
|
||
|
||
it('可与视口工具条共享受控放置方式', () => {
|
||
const onPlacementModeChange = vi.fn();
|
||
render(
|
||
<MapAssetLibrary
|
||
disabled={false}
|
||
terrainSize={8}
|
||
placementMode="locked"
|
||
onPlacementModeChange={onPlacementModeChange}
|
||
onAdd={() => {}}
|
||
onSelectTerrain={() => {}}
|
||
/>,
|
||
);
|
||
expect(screen.getByLabelText('新增资产放置方式')).toHaveValue('locked');
|
||
fireEvent.change(screen.getByLabelText('新增资产放置方式'), {
|
||
target: { value: 'gravity' },
|
||
});
|
||
expect(onPlacementModeChange).toHaveBeenCalledWith('gravity');
|
||
});
|
||
|
||
it('拖动物理原语时写入类型和放置方式', () => {
|
||
const values = new Map<string, string>();
|
||
const dataTransfer = {
|
||
effectAllowed: 'none',
|
||
setData: (type: string, value: string) => values.set(type, value),
|
||
} as unknown as DataTransfer;
|
||
renderLibrary();
|
||
fireEvent.change(screen.getByLabelText('新增资产放置方式'), {
|
||
target: { value: 'locked' },
|
||
});
|
||
fireEvent.dragStart(document.querySelector('[data-map-asset="ramp"]')!, { dataTransfer });
|
||
expect(decodeMapLibraryDragPayload(values.get(MAP_LIBRARY_DRAG_MIME) ?? '')).toEqual({
|
||
kind: 'certified',
|
||
type: 'ramp',
|
||
placementMode: 'locked',
|
||
});
|
||
});
|
||
|
||
it('以示意图卡片添加或拖动预设地形', () => {
|
||
const onSelectTerrain = vi.fn();
|
||
const values = new Map<string, string>();
|
||
const dataTransfer = {
|
||
effectAllowed: 'none',
|
||
setData: (type: string, value: string) => values.set(type, value),
|
||
} as unknown as DataTransfer;
|
||
renderLibrary(undefined, onSelectTerrain);
|
||
expect(screen.getAllByText('8.00 × 8.00 m')).toHaveLength(9);
|
||
fireEvent.click(screen.getByRole('button', { name: '添加随机粗糙地形' }));
|
||
fireEvent.dragStart(document.querySelector('[data-system-terrain="wave"]')!, { dataTransfer });
|
||
expect(onSelectTerrain).toHaveBeenCalledWith('rough');
|
||
expect(decodeMapLibraryDragPayload(values.get(MAP_LIBRARY_DRAG_MIME) ?? '')).toEqual({
|
||
kind: 'terrain',
|
||
preset: 'wave',
|
||
});
|
||
});
|
||
});
|