Files
Genarrative/src/components/image-editor/ImageCanvasTopbarView.test.tsx
T
wuxiangwanzi 25421140bf 优化画布泥点入口
让画布顶部泥点余额按钮复用创作页充值和兑换码入口

抽取账户充值支付结果与确认弹窗组件供创作页和画布页共用

补充画布泥点入口回归测试和编辑器技术文档
2026-06-22 21:08:33 +08:00

183 lines
5.6 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: [],
walletBalanceLabel: '1,234泥点',
isWalletBalanceLoading: false,
assetExportStatus: null,
isExportingAssets: false,
setProjectRenameValue: vi.fn(),
startProjectRename: vi.fn(),
cancelProjectRename: vi.fn(),
submitProjectRename: vi.fn(),
resetProjectRenameError: vi.fn(),
exportCanvasAssets: vi.fn(),
onOpenShortcuts: vi.fn(),
onOpenWallet: 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.queryByText('画布')).toBeNull();
expect(
screen.getByRole('link', { name: '返回项目页面' }).getAttribute('href'),
).toBe('/project');
fireEvent.click(screen.getByRole('button', { name: '编辑项目名称' }));
expect(props.startProjectRename).toHaveBeenCalledTimes(1);
fireEvent.click(screen.getByRole('button', { name: '查看画布快捷键' }));
expect(props.onOpenShortcuts).toHaveBeenCalledTimes(1);
});
it('shows the current mud point balance in the topbar', () => {
const props = renderTopbar({
walletBalanceLabel: '1.2万泥点',
});
const walletChip = screen.getByRole('button', {
name: '泥点余额 1.2万泥点',
});
expect(walletChip.textContent).toBe('1.2万泥点');
expect(walletChip.querySelector('img')?.getAttribute('src')).toBe(
'/creation-home/topbar-wallet.png',
);
fireEvent.click(walletChip);
expect(props.onOpenWallet).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={[]}
walletBalanceLabel="0泥点"
isWalletBalanceLoading={false}
assetExportStatus={null}
isExportingAssets={false}
setProjectRenameValue={vi.fn()}
startProjectRename={vi.fn()}
cancelProjectRename={vi.fn()}
submitProjectRename={vi.fn()}
resetProjectRenameError={vi.fn()}
exportCanvasAssets={exportCanvasAssets}
onOpenShortcuts={vi.fn()}
onOpenWallet={vi.fn()}
/>,
);
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()]}
walletBalanceLabel="0泥点"
isWalletBalanceLoading={false}
assetExportStatus={{
tone: 'success',
message: '画布素材已导出',
}}
isExportingAssets={false}
setProjectRenameValue={vi.fn()}
startProjectRename={vi.fn()}
cancelProjectRename={vi.fn()}
submitProjectRename={vi.fn()}
resetProjectRenameError={vi.fn()}
exportCanvasAssets={exportCanvasAssets}
onOpenShortcuts={vi.fn()}
onOpenWallet={vi.fn()}
/>,
);
fireEvent.click(screen.getByRole('button', { name: '下载画布素材' }));
expect(exportCanvasAssets).toHaveBeenCalledTimes(1);
expect(screen.getByRole('status').textContent).toBe('画布素材已导出');
});
});