新增图片画布项目页
新增 /project 项目页和我的页项目入口 补齐图片画布工程列表、重命名和删除 API 支持 /editor/canvas 按 projectid 加载指定工程 更新图片画布文档、TRACKING 和对应测试
This commit is contained in:
125
src/components/project/ProjectGalleryView.test.tsx
Normal file
125
src/components/project/ProjectGalleryView.test.tsx
Normal file
@@ -0,0 +1,125 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen, waitFor, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { ProjectGalleryView } from './ProjectGalleryView';
|
||||
|
||||
const listEditorProjectsMock = vi.hoisted(() => vi.fn());
|
||||
const createEditorProjectMock = vi.hoisted(() => vi.fn());
|
||||
const renameEditorProjectMock = vi.hoisted(() => vi.fn());
|
||||
const deleteEditorProjectMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock('../../services/image-editor/editorProjectClient', () => ({
|
||||
listEditorProjects: listEditorProjectsMock,
|
||||
createEditorProject: createEditorProjectMock,
|
||||
renameEditorProject: renameEditorProjectMock,
|
||||
deleteEditorProject: deleteEditorProjectMock,
|
||||
}));
|
||||
|
||||
const projectItems = [
|
||||
{
|
||||
projectId: 'editor-project-1',
|
||||
title: '角色设定板',
|
||||
viewport: { x: 0, y: 0, scale: 1 },
|
||||
layers: [{ layerId: 'layer-1', resourceId: 'resource-1' }],
|
||||
resources: [
|
||||
{
|
||||
resourceId: 'resource-1',
|
||||
projectId: 'editor-project-1',
|
||||
imageSrc: 'data:image/png;base64,one',
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
sourceType: 'uploaded',
|
||||
},
|
||||
],
|
||||
updatedAt: '2026-06-12T08:00:00.000Z',
|
||||
},
|
||||
{
|
||||
projectId: 'editor-project-2',
|
||||
title: '场景草图',
|
||||
viewport: { x: 0, y: 0, scale: 1 },
|
||||
layers: [],
|
||||
resources: [],
|
||||
updatedAt: '2026-06-12T07:00:00.000Z',
|
||||
},
|
||||
];
|
||||
|
||||
describe('ProjectGalleryView', () => {
|
||||
afterEach(() => {
|
||||
listEditorProjectsMock.mockReset();
|
||||
createEditorProjectMock.mockReset();
|
||||
renameEditorProjectMock.mockReset();
|
||||
deleteEditorProjectMock.mockReset();
|
||||
});
|
||||
|
||||
it('opens a project from the gallery card', async () => {
|
||||
const onOpenProject = vi.fn();
|
||||
listEditorProjectsMock.mockResolvedValueOnce(projectItems);
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<ProjectGalleryView onOpenProject={onOpenProject} />);
|
||||
|
||||
await screen.findByText('角色设定板');
|
||||
await user.click(screen.getByRole('button', { name: '打开项目角色设定板' }));
|
||||
|
||||
expect(onOpenProject).toHaveBeenCalledWith('editor-project-1');
|
||||
});
|
||||
|
||||
it('renames and deletes a project from the hover menu', async () => {
|
||||
listEditorProjectsMock.mockResolvedValueOnce(projectItems);
|
||||
renameEditorProjectMock.mockResolvedValueOnce({
|
||||
...projectItems[0],
|
||||
title: '新角色设定板',
|
||||
});
|
||||
deleteEditorProjectMock.mockResolvedValueOnce('editor-project-2');
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<ProjectGalleryView onOpenProject={vi.fn()} />);
|
||||
|
||||
await screen.findByText('角色设定板');
|
||||
await user.click(screen.getByRole('button', { name: '打开项目角色设定板菜单' }));
|
||||
await user.click(screen.getByRole('menuitem', { name: /重命名/u }));
|
||||
await user.clear(screen.getByLabelText('项目名称'));
|
||||
await user.type(screen.getByLabelText('项目名称'), '新角色设定板');
|
||||
await user.click(screen.getByRole('button', { name: '保存' }));
|
||||
|
||||
expect(renameEditorProjectMock).toHaveBeenCalledWith(
|
||||
'editor-project-1',
|
||||
'新角色设定板',
|
||||
);
|
||||
await screen.findByText('新角色设定板');
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '打开项目场景草图菜单' }));
|
||||
await user.click(screen.getByRole('menuitem', { name: /删除/u }));
|
||||
|
||||
expect(deleteEditorProjectMock).toHaveBeenCalledWith('editor-project-2');
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('场景草图')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
it('supports batch selection actions from the bottom toolbar', async () => {
|
||||
listEditorProjectsMock.mockResolvedValueOnce(projectItems);
|
||||
deleteEditorProjectMock.mockResolvedValue('deleted');
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<ProjectGalleryView onOpenProject={vi.fn()} />);
|
||||
|
||||
await screen.findByText('角色设定板');
|
||||
await user.click(screen.getByRole('button', { name: '选择' }));
|
||||
const toolbar = screen.getByRole('toolbar', { name: '批量操作' });
|
||||
|
||||
await user.click(within(toolbar).getByRole('button', { name: '全选' }));
|
||||
|
||||
expect(
|
||||
within(toolbar).getByRole('button', { name: '取消全选 · 已选 2' }),
|
||||
).toBeTruthy();
|
||||
|
||||
await user.click(within(toolbar).getByRole('button', { name: '删除' }));
|
||||
|
||||
expect(deleteEditorProjectMock).toHaveBeenCalledWith('editor-project-1');
|
||||
expect(deleteEditorProjectMock).toHaveBeenCalledWith('editor-project-2');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user