This commit is contained in:
2026-05-14 01:11:58 +08:00
parent b13870f71b
commit 5a55180b78
61 changed files with 5050 additions and 1057 deletions

View File

@@ -20,11 +20,22 @@ vi.mock('../ResolvedAssetImage', () => ({
src,
alt,
className,
'data-testid': dataTestId,
}: {
src?: string | null;
alt?: string;
className?: string;
}) => (src ? <img src={src} alt={alt} className={className} /> : null),
'data-testid'?: string;
}) => (
src ? (
<img
src={src}
alt={alt}
className={className}
data-testid={dataTestId}
/>
) : null
),
}));
vi.mock('../../services/puzzle-works/puzzleAssetClient', () => ({
@@ -37,6 +48,16 @@ vi.mock('../../services/puzzle-works', () => ({
updatePuzzleWork: vi.fn(),
}));
vi.mock('../../hooks/useResolvedAssetReadUrl', () => ({
useResolvedAssetReadUrl: (src?: string | null) => ({
resolvedUrl: src
? `https://signed.example.com/${src.replace(/^\/+/u, '')}`
: '',
isResolving: false,
shouldResolve: Boolean(src?.trim().startsWith('/generated-')),
}),
}));
afterEach(() => {
vi.useRealTimers();
vi.clearAllMocks();
@@ -157,6 +178,8 @@ describe('PuzzleResultView', () => {
expect(screen.getByRole('button', { name: '拼图关卡' })).toBeTruthy();
expect(screen.getByRole('button', { name: '作品信息' })).toBeTruthy();
expect(screen.getByRole('button', { name: '素材配置' })).toBeTruthy();
expect(screen.queryByRole('button', { name: '音乐' })).toBeNull();
expect(screen.getByText('雨夜猫街')).toBeTruthy();
expect(screen.getByText('获得更多积分激励')).toBeTruthy();
@@ -171,6 +194,33 @@ describe('PuzzleResultView', () => {
);
});
test('result action bar restores draft trial entry', () => {
const onStartTestRun = vi.fn();
render(
<PuzzleResultView
session={createSession()}
onBack={() => {}}
onExecuteAction={() => {}}
onStartTestRun={onStartTestRun}
/>,
);
fireEvent.click(screen.getByRole('button', { name: '试玩' }));
expect(onStartTestRun).toHaveBeenCalledWith(
expect.objectContaining({
workTitle: '暖灯猫街作品',
levels: [
expect.objectContaining({
levelId: 'puzzle-level-1',
levelName: '雨夜猫街',
}),
],
}),
);
});
test('auto saves work info and levels through one payload', async () => {
vi.useFakeTimers();
vi.mocked(puzzleWorksService.updatePuzzleWork).mockResolvedValue({
@@ -645,7 +695,7 @@ describe('PuzzleResultView', () => {
/>,
);
fireEvent.click(screen.getByRole('button', { name: 'UI' }));
fireEvent.click(screen.getByRole('button', { name: '素材配置' }));
expect(screen.getByAltText('拼图UI背景图').getAttribute('src')).toBe(
'/generated-puzzle-assets/session/ui/background.png',
@@ -657,6 +707,11 @@ describe('PuzzleResultView', () => {
fireEvent.click(screen.getByRole('button', { name: '预览UI' }));
const preview = screen.getByRole('dialog', { name: 'UI预览' });
expect(
within(preview)
.getByTestId('puzzle-ui-runtime-preview-background')
.getAttribute('src'),
).toBe('/generated-puzzle-assets/session/ui/background.png');
expect(within(preview).getByLabelText('拼图区边界')).toBeTruthy();
});
@@ -671,11 +726,12 @@ describe('PuzzleResultView', () => {
/>,
);
fireEvent.click(screen.getByRole('button', { name: 'UI' }));
fireEvent.click(screen.getByRole('button', { name: '素材配置' }));
fireEvent.change(screen.getByLabelText('拼图UI背景提示词'), {
target: { value: '新拼图UI背景提示词' },
});
fireEvent.click(screen.getByRole('button', { name: '生成UI背景' }));
expect(screen.getByRole('button', { name: /生成UI背景 · 2光点/u })).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: /生成UI背景/u }));
expect(onExecuteAction).toHaveBeenCalledWith({
action: 'generate_puzzle_ui_background',
@@ -696,6 +752,46 @@ describe('PuzzleResultView', () => {
]);
});
test('素材配置背景音乐试听使用签名地址', () => {
const base = createSession();
const level = base.draft!.levels![0]!;
render(
<PuzzleResultView
session={createSession({
draft: {
...base.draft!,
levels: [
{
...level,
backgroundMusic: {
taskId: 'music-task-1',
provider: 'vector-engine-suno',
assetObjectId: 'asset-music-1',
assetKind: 'puzzle_background_music',
audioSrc: '/generated-puzzle-assets/session/audio/music.mp3',
prompt: '',
title: '雨夜轻响',
updatedAt: '2026-05-12T10:00:00.000Z',
},
},
],
},
})}
onBack={() => {}}
onExecuteAction={() => {}}
/>,
);
fireEvent.click(screen.getByRole('button', { name: '素材配置' }));
fireEvent.click(screen.getByRole('button', { name: '背景音乐' }));
expect(screen.getByRole('button', { name: /重新生成音乐 · 5光点/u })).toBeTruthy();
expect(screen.getByLabelText('拼图背景音乐').getAttribute('src')).toBe(
'https://signed.example.com/generated-puzzle-assets/session/audio/music.mp3',
);
});
test('auto saves UI background prompt edits through levels', async () => {
vi.useFakeTimers();
vi.mocked(puzzleWorksService.updatePuzzleWork).mockResolvedValue({
@@ -711,7 +807,7 @@ describe('PuzzleResultView', () => {
/>,
);
fireEvent.click(screen.getByRole('button', { name: 'UI' }));
fireEvent.click(screen.getByRole('button', { name: '素材配置' }));
fireEvent.change(screen.getByLabelText('拼图UI背景提示词'), {
target: { value: '新的自动保存UI背景提示词' },
});