补充 UI 编辑器保存结果测试
覆盖保存和生成成功弹窗与项目相对路径复制 覆盖保存失败、冲突和剪贴板失败反馈
This commit is contained in:
@@ -13,6 +13,10 @@ import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
vi.mock('@tauri-apps/api/core', () => ({ invoke: vi.fn() }));
|
||||
|
||||
vi.mock('@tauri-apps/plugin-clipboard-manager', () => ({
|
||||
writeText: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('../src/components/AssetImporter', () => ({
|
||||
AssetImporter: ({ open }: { open: boolean }) =>
|
||||
open ? createElement('div', { role: 'dialog' }, '素材导入器') : null,
|
||||
@@ -24,6 +28,7 @@ vi.mock('../src/components/modal/ThemedModal', () => ({
|
||||
}));
|
||||
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { writeText } from '@tauri-apps/plugin-clipboard-manager';
|
||||
|
||||
import type { Node as UiNode } from '../src/features/ui-editor/types/Node';
|
||||
import type { State } from '../src/features/ui-editor/types/State';
|
||||
@@ -789,17 +794,13 @@ describe('UiEditorPage', () => {
|
||||
fireEvent.click(await screen.findByRole('button', { name: '保存' }));
|
||||
fireEvent.click(await screen.findByRole('button', { name: '仍然保存' }));
|
||||
|
||||
expect((await screen.findByRole('alert')).textContent).toContain(
|
||||
expect((await screen.findByRole('dialog')).textContent).toContain(
|
||||
'保存失败,请稍后重试。',
|
||||
);
|
||||
expect(screen.getByRole('alert').textContent).not.toContain(
|
||||
'临时存储不可用',
|
||||
);
|
||||
expect(screen.getByRole('button', { name: '保存' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '重试保存' })).toBeTruthy();
|
||||
expect(stateStore.save).toHaveBeenCalledTimes(1);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '保存' }));
|
||||
fireEvent.click(await screen.findByRole('button', { name: '仍然保存' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '重试保存' }));
|
||||
expect(stateStore.save).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
@@ -823,8 +824,89 @@ describe('UiEditorPage', () => {
|
||||
fireEvent.click(await screen.findByRole('button', { name: '保存' }));
|
||||
fireEvent.click(await screen.findByRole('button', { name: '仍然保存' }));
|
||||
|
||||
expect((await screen.findByRole('alert')).textContent).toContain(
|
||||
expect((await screen.findByRole('dialog')).textContent).toContain(
|
||||
'资源已在别处更新;请重新加载后再保存。',
|
||||
);
|
||||
});
|
||||
|
||||
it('shows a generated path modal and copies the project-relative path', async () => {
|
||||
const stateStore: IUiDesignStateStore = {
|
||||
load: vi.fn().mockResolvedValue(structuredClone(EMPTY_SNAPSHOT)),
|
||||
save: vi.fn().mockResolvedValue({
|
||||
status: 'saved',
|
||||
state: structuredClone(EMPTY_SNAPSHOT.state),
|
||||
revision: 1,
|
||||
committedProjectRevision: 1,
|
||||
}),
|
||||
generateCode: vi.fn().mockResolvedValue({
|
||||
relativePath: 'ui/generated-example.js',
|
||||
treeExports: ['Example'],
|
||||
treeCount: 1,
|
||||
nodeCount: 2,
|
||||
}),
|
||||
};
|
||||
vi.mocked(writeText).mockResolvedValue(undefined);
|
||||
|
||||
render(
|
||||
createElement(UiEditorPage, {
|
||||
projectPath: '/tmp/ui-editor',
|
||||
resourceId: 'ui-resource',
|
||||
stateStore,
|
||||
}),
|
||||
);
|
||||
|
||||
fireEvent.click(
|
||||
await screen.findByRole('button', { name: '保存并生成代码' }),
|
||||
);
|
||||
fireEvent.click(
|
||||
await screen.findByRole('button', { name: '仍然保存并生成' }),
|
||||
);
|
||||
|
||||
const dialog = await screen.findByRole('dialog');
|
||||
expect(dialog.textContent).toContain('代码已生成');
|
||||
expect(dialog.textContent).toContain('ui/generated-example.js');
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '复制路径' }));
|
||||
await waitFor(() =>
|
||||
expect(writeText).toHaveBeenCalledWith('ui/generated-example.js'),
|
||||
);
|
||||
expect(screen.getByRole('button', { name: '已复制' })).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows a manual-copy hint when the native clipboard rejects a path', async () => {
|
||||
const stateStore: IUiDesignStateStore = {
|
||||
load: vi.fn().mockResolvedValue(structuredClone(EMPTY_SNAPSHOT)),
|
||||
save: vi.fn().mockResolvedValue({
|
||||
status: 'saved',
|
||||
state: structuredClone(EMPTY_SNAPSHOT.state),
|
||||
revision: 1,
|
||||
committedProjectRevision: 1,
|
||||
}),
|
||||
generateCode: vi.fn().mockResolvedValue({
|
||||
relativePath: 'ui/generated-example.js',
|
||||
treeExports: ['Example'],
|
||||
treeCount: 1,
|
||||
nodeCount: 2,
|
||||
}),
|
||||
};
|
||||
vi.mocked(writeText).mockRejectedValue(new Error('clipboard unavailable'));
|
||||
|
||||
render(
|
||||
createElement(UiEditorPage, {
|
||||
projectPath: '/tmp/ui-editor',
|
||||
resourceId: 'ui-resource',
|
||||
stateStore,
|
||||
}),
|
||||
);
|
||||
|
||||
fireEvent.click(
|
||||
await screen.findByRole('button', { name: '保存并生成代码' }),
|
||||
);
|
||||
fireEvent.click(
|
||||
await screen.findByRole('button', { name: '仍然保存并生成' }),
|
||||
);
|
||||
fireEvent.click(await screen.findByRole('button', { name: '复制路径' }));
|
||||
|
||||
expect(await screen.findByText('复制失败,请手动复制路径。')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user