新增 ImageCanvasTopbarView 承载返回项目入口和项目标题区域 新增顶栏视图测试覆盖重命名和导出入口 精简 ImageCanvasEditorView 的顶部栏 JSX 更新图片画布拆分计划和 TRACKING 验证记录
148 lines
4.5 KiB
TypeScript
148 lines
4.5 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import type { CanvasLayer } from './ImageCanvasEditorTypes';
|
|
import { ImageCanvasTopbarView } from './ImageCanvasTopbarView';
|
|
|
|
function createLayer(overrides: Partial<CanvasLayer> = {}): CanvasLayer {
|
|
const id = overrides.id ?? 'layer-a';
|
|
return {
|
|
id,
|
|
resourceId: `resource-${id}`,
|
|
title: id,
|
|
src: `data:image/png;base64,${id}`,
|
|
x: 0,
|
|
y: 0,
|
|
width: 320,
|
|
height: 180,
|
|
originalWidth: 320,
|
|
originalHeight: 180,
|
|
zIndex: 1,
|
|
sourceType: 'uploaded',
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function renderTopbar(
|
|
overrides: Partial<
|
|
Parameters<typeof ImageCanvasTopbarView>[0]
|
|
> = {},
|
|
) {
|
|
const props: Parameters<typeof ImageCanvasTopbarView>[0] = {
|
|
projectId: 'project-a',
|
|
projectTitle: '默认项目',
|
|
projectRenameValue: '默认项目',
|
|
isRenamingProject: false,
|
|
isProjectRenameSaving: false,
|
|
projectRenameError: null,
|
|
layers: [],
|
|
assetExportStatus: null,
|
|
isExportingAssets: false,
|
|
setProjectRenameValue: vi.fn(),
|
|
startProjectRename: vi.fn(),
|
|
cancelProjectRename: vi.fn(),
|
|
submitProjectRename: vi.fn(),
|
|
resetProjectRenameError: vi.fn(),
|
|
exportCanvasAssets: vi.fn(),
|
|
...overrides,
|
|
};
|
|
|
|
render(<ImageCanvasTopbarView {...props} />);
|
|
|
|
return props;
|
|
}
|
|
|
|
describe('ImageCanvasTopbarView', () => {
|
|
it('shows the project title and project gallery link', () => {
|
|
const props = renderTopbar();
|
|
|
|
expect(screen.getByRole('heading', { name: '默认项目' })).toBeTruthy();
|
|
expect(
|
|
screen.getByRole('link', { name: '返回项目页面' }).getAttribute('href'),
|
|
).toBe('/project');
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: '编辑项目名称' }));
|
|
|
|
expect(props.startProjectRename).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('submits, resets, and cancels project rename edits', () => {
|
|
const props = renderTopbar({
|
|
isRenamingProject: true,
|
|
projectRenameValue: '草稿项目',
|
|
projectRenameError: '项目名称不能为空',
|
|
});
|
|
|
|
const input = screen.getByLabelText('项目名称');
|
|
fireEvent.change(input, { target: { value: '新项目' } });
|
|
fireEvent.click(screen.getByRole('button', { name: '保存项目名称' }));
|
|
|
|
expect(props.setProjectRenameValue).toHaveBeenCalledWith('新项目');
|
|
expect(props.resetProjectRenameError).toHaveBeenCalledTimes(1);
|
|
expect(props.submitProjectRename).toHaveBeenCalledWith('project-a');
|
|
expect(screen.getByRole('alert').textContent).toBe('项目名称不能为空');
|
|
|
|
fireEvent.keyDown(input, { key: 'Escape' });
|
|
|
|
expect(props.cancelProjectRename).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('exports only when canvas has exportable layers and shows export status', () => {
|
|
const exportCanvasAssets = vi.fn();
|
|
const { rerender } = render(
|
|
<ImageCanvasTopbarView
|
|
projectId="project-a"
|
|
projectTitle="默认项目"
|
|
projectRenameValue="默认项目"
|
|
isRenamingProject={false}
|
|
isProjectRenameSaving={false}
|
|
projectRenameError={null}
|
|
layers={[]}
|
|
assetExportStatus={null}
|
|
isExportingAssets={false}
|
|
setProjectRenameValue={vi.fn()}
|
|
startProjectRename={vi.fn()}
|
|
cancelProjectRename={vi.fn()}
|
|
submitProjectRename={vi.fn()}
|
|
resetProjectRenameError={vi.fn()}
|
|
exportCanvasAssets={exportCanvasAssets}
|
|
/>,
|
|
);
|
|
|
|
expect(
|
|
(screen.getByRole('button', { name: '下载画布素材' }) as HTMLButtonElement)
|
|
.disabled,
|
|
).toBe(true);
|
|
|
|
rerender(
|
|
<ImageCanvasTopbarView
|
|
projectId="project-a"
|
|
projectTitle="默认项目"
|
|
projectRenameValue="默认项目"
|
|
isRenamingProject={false}
|
|
isProjectRenameSaving={false}
|
|
projectRenameError={null}
|
|
layers={[createLayer()]}
|
|
assetExportStatus={{
|
|
tone: 'success',
|
|
message: '画布素材已导出',
|
|
}}
|
|
isExportingAssets={false}
|
|
setProjectRenameValue={vi.fn()}
|
|
startProjectRename={vi.fn()}
|
|
cancelProjectRename={vi.fn()}
|
|
submitProjectRename={vi.fn()}
|
|
resetProjectRenameError={vi.fn()}
|
|
exportCanvasAssets={exportCanvasAssets}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: '下载画布素材' }));
|
|
|
|
expect(exportCanvasAssets).toHaveBeenCalledTimes(1);
|
|
expect(screen.getByRole('status').textContent).toBe('画布素材已导出');
|
|
});
|
|
});
|