This commit is contained in:
2026-05-10 22:20:54 +08:00
parent d6219f1a0c
commit 192accd796
92 changed files with 7045 additions and 1559 deletions

View File

@@ -1,11 +1,37 @@
/* @vitest-environment jsdom */
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import {
act,
fireEvent,
render,
screen,
waitFor,
within,
} from '@testing-library/react';
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
import type { PuzzleAgentSessionSnapshot } from '../../../packages/shared/src/contracts/puzzleAgentSession';
import { puzzleAssetClient } from '../../services/puzzle-works/puzzleAssetClient';
import { PuzzleAgentWorkspace } from './PuzzleAgentWorkspace';
vi.mock('../ResolvedAssetImage', () => ({
ResolvedAssetImage: ({
src,
alt,
className,
}: {
src?: string | null;
alt?: string;
className?: string;
}) => (src ? <img src={src} alt={alt} className={className} /> : null),
}));
vi.mock('../../services/puzzle-works/puzzleAssetClient', () => ({
puzzleAssetClient: {
listHistoryAssets: vi.fn(),
},
}));
const baseSession: PuzzleAgentSessionSnapshot = {
sessionId: 'puzzle-session-1',
currentTurn: 3,
@@ -70,6 +96,7 @@ afterEach(() => {
vi.useRealTimers();
vi.unstubAllGlobals();
vi.restoreAllMocks();
vi.clearAllMocks();
});
function stubReferenceImageUpload(dataUrl: string, width = 512, height = 512) {
@@ -221,6 +248,66 @@ test('puzzle workspace keeps the reference image upload as a primary panel', ()
);
});
test('puzzle workspace selects a history image from the upload card', async () => {
const onCreateFromForm = vi.fn();
vi.mocked(puzzleAssetClient.listHistoryAssets).mockResolvedValue([
{
assetObjectId: 'asset-history-1',
assetKind: 'puzzle_cover_image',
imageSrc: '/generated-puzzle-assets/history/image.png',
ownerUserId: 'user-1',
ownerLabel: '账号 user-1',
profileId: null,
entityId: 'puzzle-session-1',
createdAt: '2026-04-27T10:00:00.000Z',
updatedAt: '2026-04-27T10:00:00.000Z',
},
]);
render(
<PuzzleAgentWorkspace
session={null}
onBack={() => {}}
onSubmitMessage={() => {}}
onExecuteAction={() => {}}
onCreateFromForm={onCreateFromForm}
/>,
);
const historyButton = screen.getByRole('button', { name: '选择历史图片' });
expect(historyButton.closest('.puzzle-image-upload-card')).toBeTruthy();
expect(screen.getByText('历史').closest('.puzzle-image-upload-card')).toBeTruthy();
fireEvent.click(historyButton);
const picker = await screen.findByRole('dialog', {
name: '选择历史图片',
});
fireEvent.click(
await within(picker).findByRole('button', { name: / user-1/u }),
);
await waitFor(() => {
expect(screen.queryByRole('dialog', { name: '选择历史图片' })).toBeNull();
});
expect(screen.getByAltText('拼图图片')).toHaveProperty(
'src',
expect.stringContaining('/generated-puzzle-assets/history/image.png'),
);
fireEvent.change(screen.getByLabelText('画面AI重绘要求提示词'), {
target: { value: '保留历史图里的主体,改成晴天花园。' },
});
fireEvent.click(screen.getByRole('button', { name: /稿/u }));
expect(onCreateFromForm).toHaveBeenCalledWith({
seedText: '保留历史图里的主体,改成晴天花园。',
pictureDescription: '保留历史图里的主体,改成晴天花园。',
referenceImageSrc: '/generated-puzzle-assets/history/image.png',
imageModel: 'gpt-image-2',
aiRedraw: true,
});
});
test('puzzle upload card stays light in light theme', () => {
const onCreateFromForm = vi.fn();
const { container } = render(
@@ -237,6 +324,9 @@ test('puzzle upload card stays light in light theme', () => {
const uploadLabel = screen.getByText('点击上传拼图图片');
expect(uploadLabel).toBeTruthy();
expect(uploadLabel.closest('.puzzle-image-upload-card')).toBeTruthy();
expect(uploadLabel.className).not.toContain('rounded-full');
expect(uploadLabel.className).not.toContain('bg-white/94');
expect(uploadLabel.className).not.toContain('border');
expect(screen.queryByText('AI重绘')).toBeNull();
expect(container.querySelector('.puzzle-image-upload-card')?.className).toContain(
'bg-white/90',