This commit is contained in:
2026-05-08 20:48:29 +08:00
parent abf1f1ebea
commit 94975e4735
82 changed files with 7786 additions and 1012 deletions

View File

@@ -145,7 +145,7 @@ test('puzzle workspace submits the work form instead of agent chat', () => {
fireEvent.change(screen.getByLabelText('画面描述'), {
target: { value: '一只猫在雨夜灯牌下回头。' },
});
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
expect(onCreateFromForm).toHaveBeenCalledWith({
seedText: '一只猫在雨夜灯牌下回头。',
@@ -178,9 +178,20 @@ test('puzzle workspace keeps the reference image upload as a primary panel', ()
expect(uploadCard).not.toBeNull();
expect(uploadCard?.closest('.platform-subpanel')).toBeNull();
expect(container.querySelector('.puzzle-image-upload-card')).toBeTruthy();
expect(container.querySelector('.puzzle-creation-form-body')?.className).toContain(
'overflow-hidden',
);
expect(container.querySelector('.puzzle-image-field')?.className).toContain(
'flex-1',
);
expect(screen.getByText('拼图画面')).toBeTruthy();
expect(screen.getByText('点击上传拼图图片')).toBeTruthy();
expect(
screen
.getByText('若没有合适的图片可以通过填写画面描述生成画面')
.closest('.puzzle-image-upload-card'),
).toBeTruthy();
expect(screen.getByText('点击上传拼图图片').closest('.puzzle-image-upload-card')).toBeTruthy();
expect(screen.queryByRole('switch', { name: 'AI重绘' })).toBeNull();
expect(screen.queryByLabelText('拼图创作模板')).toBeNull();
expect(
@@ -190,15 +201,19 @@ test('puzzle workspace keeps the reference image upload as a primary panel', ()
(screen.getByLabelText('画面描述') as HTMLTextAreaElement).placeholder,
).toBe('');
expect(screen.queryByText(//u)).toBeNull();
expect(screen.getByLabelText('画面描述').className).toContain(
'min-h-[clamp(5rem,15svh,7rem)]',
);
expect(screen.getByLabelText('画面描述').className).toContain('h-[6rem]');
expect(uploadCard?.className).toContain('aspect-square');
expect(uploadCard?.className).toContain('h-full');
expect(
screen
.getByRole('button', { name: /稿/u })
.parentElement?.className,
).toContain('justify-center');
fireEvent.change(screen.getByLabelText('画面描述'), {
target: { value: '一只猫在阳光窗台上看着毛线球。' },
});
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
expect(onCreateFromForm).toHaveBeenCalledWith(
expect.objectContaining({
pictureDescription: '一只猫在阳光窗台上看着毛线球。',
@@ -221,7 +236,7 @@ test('puzzle upload card stays light in light theme', () => {
expect(container.querySelector('.puzzle-image-upload-card')).toBeTruthy();
const uploadLabel = screen.getByText('点击上传拼图图片');
expect(uploadLabel).toBeTruthy();
expect(uploadLabel.closest('.puzzle-image-upload-card')).toBeNull();
expect(uploadLabel.closest('.puzzle-image-upload-card')).toBeTruthy();
expect(screen.queryByText('AI重绘')).toBeNull();
expect(container.querySelector('.puzzle-image-upload-card')?.className).toContain(
'bg-white/90',
@@ -245,7 +260,7 @@ test('puzzle workspace falls back to compile action for restored sessions', () =
/>,
);
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
expect(onCreateFromForm).not.toHaveBeenCalled();
expect(onExecuteAction).toHaveBeenCalledWith({
@@ -278,7 +293,7 @@ test('puzzle workspace switches the image model from the description box', () =>
fireEvent.click(screen.getByRole('button', { name: '图片模型' }));
expect(screen.queryByRole('menuitemradio', { name: '原模型' })).toBeNull();
fireEvent.click(screen.getByRole('menuitemradio', { name: 'nanobanana2' }));
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
expect(onCreateFromForm).toHaveBeenCalledWith(
expect.objectContaining({
@@ -390,7 +405,7 @@ test('puzzle workspace hides prompt and cost when AI redraw is off', async () =>
expect(screen.queryByLabelText('画面AI重绘要求提示词')).toBeNull();
expect(screen.queryByText('消耗2光点')).toBeNull();
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
expect(onCreateFromForm).toHaveBeenCalledWith({
seedText: 'first-level.png',
@@ -425,6 +440,51 @@ test('puzzle workspace shows AI redraw switch only after upload', async () => {
await waitFor(() => {
expect(screen.getByRole('switch', { name: 'AI重绘' })).toBeTruthy();
});
expect(
screen.getByRole('switch', { name: 'AI重绘' }).closest('.puzzle-image-upload-card'),
).toBeTruthy();
expect(screen.getByRole('button', { name: '移除拼图图片' })).toBeTruthy();
expect(screen.queryByText('点击上传拼图图片')).toBeNull();
});
test('puzzle workspace confirms before removing uploaded image', async () => {
const uploadedDataUrl = 'data:image/png;base64,uploaded-square';
stubReferenceImageUpload(uploadedDataUrl);
render(
<PuzzleAgentWorkspace
session={null}
onBack={() => {}}
onSubmitMessage={() => {}}
onExecuteAction={() => {}}
onCreateFromForm={() => {}}
/>,
);
fireEvent.change(screen.getByLabelText('上传拼图图片', { selector: 'input' }), {
target: {
files: [new File(['x'], 'first-level.png', { type: 'image/png' })],
},
});
await waitFor(() => {
expect(screen.getByAltText('拼图图片')).toBeTruthy();
});
fireEvent.click(screen.getByRole('button', { name: '移除拼图图片' }));
expect(
screen.getByRole('dialog', { name: '移除拼图图片?' }),
).toBeTruthy();
expect(screen.getByAltText('拼图图片')).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: '取消' }));
expect(screen.queryByRole('dialog', { name: '移除拼图图片?' })).toBeNull();
expect(screen.getByAltText('拼图图片')).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: '移除拼图图片' }));
fireEvent.click(screen.getByRole('button', { name: '移除' }));
expect(screen.queryByAltText('拼图图片')).toBeNull();
expect(screen.queryByRole('switch', { name: 'AI重绘' })).toBeNull();
expect(screen.getByText('点击上传拼图图片')).toBeTruthy();
});
test('puzzle workspace opens crop tool for non-square uploads', async () => {
@@ -455,6 +515,12 @@ test('puzzle workspace opens crop tool for non-square uploads', async () => {
await waitFor(() => {
expect(screen.getByRole('dialog', { name: '裁剪拼图图片' })).toBeTruthy();
});
expect(
screen.getByRole('button', { name: '拖拽右下角裁剪边界' }),
).toBeTruthy();
expect(screen.queryByText('缩放')).toBeNull();
expect(screen.queryByText('横向')).toBeNull();
expect(screen.queryByText('纵向')).toBeNull();
fireEvent.click(screen.getByRole('button', { name: '应用' }));
await waitFor(() => {