/* @vitest-environment jsdom */ import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { beforeEach, expect, test, vi } from 'vitest'; import type { JumpHopSessionResponse } from '../../../../packages/shared/src/contracts/jumpHop'; import { jumpHopClient } from '../../../services/jump-hop/jumpHopClient'; import { JumpHopCreationWorkspace } from './JumpHopCreationWorkspace'; vi.mock('../../../services/jump-hop/jumpHopClient', () => ({ jumpHopClient: { createSession: vi.fn(), }, })); const mockCreateSession = vi.mocked(jumpHopClient.createSession); beforeEach(() => { mockCreateSession.mockReset(); }); function createSessionResponse(): JumpHopSessionResponse { return { session: { sessionId: 'jump-session-1', ownerUserId: 'user-1', status: 'draft', draft: null, createdAt: '2026-05-30T10:00:00.000Z', updatedAt: '2026-05-30T10:00:00.000Z', }, }; } test('jump hop workspace submits theme payload after required field is filled', async () => { const user = userEvent.setup(); const onSubmitted = vi.fn(); const sessionResponse = createSessionResponse(); mockCreateSession.mockResolvedValue(sessionResponse); render( {}} onSubmitted={onSubmitted} />, ); const submitButton = screen.getByRole('button', { name: '生成' }); expect(submitButton).toHaveProperty('disabled', true); expect(screen.getByLabelText('主题')).toBeTruthy(); expect(screen.queryByLabelText('作品标题')).toBeNull(); expect(screen.queryByLabelText('角色提示词')).toBeNull(); await user.type(screen.getByLabelText('主题'), '云朵跳台'); expect(submitButton).toHaveProperty('disabled', false); await user.click(submitButton); await waitFor(() => { expect(mockCreateSession).toHaveBeenCalledWith({ templateId: 'jump-hop', themeText: '云朵跳台', workTitle: '云朵跳台跳一跳', workDescription: '云朵跳台主题的俯视角跳跃作品', themeTags: ['云朵跳台', '跳一跳', '休闲'], difficulty: 'standard', stylePreset: 'minimal-blocks', characterPrompt: '内置默认 3D 角色', tilePrompt: '云朵跳台主题的正面30度视角主题物体图集,物体本身作为跳跃落点', endMoodPrompt: null, }); }); expect(onSubmitted).toHaveBeenCalledWith( sessionResponse, expect.objectContaining({ templateId: 'jump-hop', themeText: '云朵跳台', }), ); }); test('jump hop workspace calls back when return button is clicked', async () => { const user = userEvent.setup(); const onBack = vi.fn(); render( {}} />); await user.click(screen.getByRole('button', { name: '返回' })); expect(onBack).toHaveBeenCalledTimes(1); }); test('jump hop workspace can defer visible chrome to the unified creation page', () => { const { container } = render( {}} onSubmitted={() => {}} showBackButton={false} unifiedChrome />, ); const workspace = container.querySelector('.jump-hop-workspace'); expect(workspace?.getAttribute('data-unified-chrome')).toBe('true'); expect(workspace?.className).toContain('max-w-none'); expect(workspace?.className).not.toContain('platform-remap-surface'); expect(screen.queryByRole('button', { name: '返回' })).toBeNull(); });