Files
Genarrative/src/components/image-editor/ImageCanvasSpecGenerationPanelView.test.tsx
kdletters d8b935317d 拆分编辑器前端画布视图
抽出素材栏、生成器、舞台工具栏和画布世界视图

补充各拆分视图的聚焦测试

更新 TRACKING.md 记录第三十四阶段验证
2026-06-17 17:48:12 +08:00

167 lines
4.8 KiB
TypeScript

/* @vitest-environment jsdom */
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import type {
GenerateDialogState,
SpecFormValues,
UploadTarget,
} from './ImageCanvasEditorTypes';
import { ImageCanvasSpecGenerationPanelView } from './ImageCanvasSpecGenerationPanelView';
function createSpecDialog(
patch: Partial<GenerateDialogState> = {},
): GenerateDialogState {
return {
mode: 'spec',
prompt: '',
status: 'idle',
specType: 'character',
specValues: {
playSetting: 'RPG玩法',
artStyle: '像素风',
bodyRatio: '3',
characterView: '右向斜侧身站姿',
customPrompt: '',
},
...patch,
};
}
function renderPanel({
dialog,
onUpdateSpecFormValue = vi.fn(),
onRequestUpload = vi.fn(),
onSubmit = vi.fn(),
}: {
dialog: GenerateDialogState;
onUpdateSpecFormValue?: (key: keyof SpecFormValues, value: string) => void;
onRequestUpload?: (target: UploadTarget) => void;
onSubmit?: (dialog: GenerateDialogState) => void;
}) {
render(
<ImageCanvasSpecGenerationPanelView
dialog={dialog}
style={{ left: 10, top: 20 }}
onUpdateSpecFormValue={onUpdateSpecFormValue}
onRequestUpload={onRequestUpload}
onSubmit={onSubmit}
/>,
);
}
describe('ImageCanvasSpecGenerationPanelView', () => {
it('renders character spec fields and forwards updates', () => {
const updateSpecFormValue = vi.fn();
renderPanel({
dialog: createSpecDialog(),
onUpdateSpecFormValue: updateSpecFormValue,
});
fireEvent.change(screen.getByLabelText('玩法设定'), {
target: { value: '战棋玩法' },
});
fireEvent.change(screen.getByLabelText('美术风格'), {
target: { value: '水彩' },
});
fireEvent.change(screen.getByLabelText('头身比'), {
target: { value: '5' },
});
fireEvent.change(screen.getByLabelText('角色视角'), {
target: { value: '左向三分之二侧身站姿' },
});
expect(updateSpecFormValue).toHaveBeenCalledWith('playSetting', '战棋玩法');
expect(updateSpecFormValue).toHaveBeenCalledWith('artStyle', '水彩');
expect(updateSpecFormValue).toHaveBeenCalledWith('bodyRatio', '5');
expect(updateSpecFormValue).toHaveBeenCalledWith(
'characterView',
'左向三分之二侧身站姿',
);
});
it('renders custom prompt and hides reference upload for icon specs', () => {
const updateSpecFormValue = vi.fn();
renderPanel({
dialog: createSpecDialog({
specType: 'custom',
specValues: {
playSetting: '',
artStyle: '',
bodyRatio: '3',
characterView: '',
customPrompt: '自定义提示',
},
}),
onUpdateSpecFormValue: updateSpecFormValue,
});
fireEvent.change(screen.getByLabelText('自定义规范提示词'), {
target: { value: '新的规范提示' },
});
expect(updateSpecFormValue).toHaveBeenCalledWith(
'customPrompt',
'新的规范提示',
);
cleanup();
renderPanel({ dialog: createSpecDialog({ specType: 'icon' }) });
expect(screen.queryByText('添加参考图')).toBeNull();
});
it('requests reference upload and submits while idle', () => {
const requestUpload = vi.fn();
const submitSpec = vi.fn();
const dialog = createSpecDialog();
renderPanel({
dialog,
onRequestUpload: requestUpload,
onSubmit: submitSpec,
});
fireEvent.click(screen.getByRole('button', { name: '添加参考图' }));
fireEvent.click(screen.getByRole('button', { name: '提交生成规范' }));
expect(requestUpload).toHaveBeenCalledWith('spec-reference');
expect(submitSpec).toHaveBeenCalledWith(dialog);
});
it('disables controls while generating and renders failure state', () => {
const submitSpec = vi.fn();
const { rerender } = render(
<ImageCanvasSpecGenerationPanelView
dialog={createSpecDialog({ status: 'generating' })}
style={{ left: 10, top: 20 }}
onUpdateSpecFormValue={vi.fn()}
onRequestUpload={vi.fn()}
onSubmit={submitSpec}
/>,
);
fireEvent.click(screen.getByRole('button', { name: '提交生成规范' }));
expect((screen.getByLabelText('玩法设定') as HTMLInputElement).disabled).toBe(
true,
);
expect(submitSpec).not.toHaveBeenCalled();
rerender(
<ImageCanvasSpecGenerationPanelView
dialog={createSpecDialog({
status: 'failed',
errorMessage: '生成失败',
})}
style={{ left: 10, top: 20 }}
onUpdateSpecFormValue={vi.fn()}
onRequestUpload={vi.fn()}
onSubmit={submitSpec}
/>,
);
expect(screen.getByRole('alert').textContent).toContain('生成失败');
});
});