167 lines
4.8 KiB
TypeScript
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('生成失败');
|
|
});
|
|
});
|