/** @vitest-environment jsdom */ import { act, render } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import type { CustomWorldAgentSessionSnapshot } from '../../../packages/shared/src/contracts/customWorldAgent'; import { type CustomWorldProfile, WorldType } from '../../types'; import { useRpgCreationEnterWorld } from './useRpgCreationEnterWorld'; function buildProfile(params: { id: string; name: string; imageSrc: string; }): CustomWorldProfile { return { id: params.id, settingText: params.name, name: params.name, subtitle: params.name, summary: params.name, tone: '测试', playerGoal: '测试', templateWorldType: WorldType.WUXIA, compatibilityTemplateWorldType: WorldType.WUXIA, majorFactions: [], coreConflicts: [], attributeSchema: { id: `${params.id}-attribute-schema`, worldId: params.id, schemaVersion: 1, generatedFrom: { worldType: WorldType.CUSTOM, worldName: params.name, settingSummary: params.name, tone: '测试', conflictCore: '测试', }, slots: [], }, playableNpcs: [ { id: `${params.id}-role`, name: '可扮演角色', title: '测试角色', role: '主角', description: '测试角色', backstory: '测试背景', personality: '测试性格', motivation: '测试动机', combatStyle: '测试战斗风格', initialAffinity: 18, relationshipHooks: [], tags: [], backstoryReveal: { publicSummary: '测试角色', privateChatUnlockAffinity: 60, chapters: [], }, skills: [], initialItems: [], imageSrc: params.imageSrc, }, ], storyNpcs: [], items: [], landmarks: [], generationMode: 'full', generationStatus: 'complete', }; } function buildSession(): CustomWorldAgentSessionSnapshot { return { sessionId: 'session-1', currentTurn: 1, anchorContent: { worldPromise: null, playerFantasy: null, themeBoundary: null, playerEntryPoint: null, coreConflict: null, keyRelationships: null, hiddenLines: null, iconicElements: null, }, progressPercent: 100, lastAssistantReply: '', stage: 'ready_to_publish', focusCardId: null, creatorIntent: null, creatorIntentReadiness: { isReady: true, completedKeys: [], missingKeys: [], }, anchorPack: null, lockState: null, draftProfile: null, messages: [], draftCards: [], pendingClarifications: [], suggestedActions: [], recommendedReplies: [], qualityFindings: [], assetCoverage: { roleAssets: [], sceneAssets: [], allRoleAssetsReady: true, allSceneAssetsReady: true, }, resultPreview: null, updatedAt: '2026-04-25T00:00:00.000Z', }; } describe('useRpgCreationEnterWorld', () => { it('Agent 草稿测试进入游戏时优先使用结果页当前 profile,而不是回退到会话快照', async () => { const resultProfile = buildProfile({ id: 'draft-profile', name: '结果页真相源', imageSrc: '/generated-characters/draft-role/portrait.png', }); const handleCustomWorldSelect = vi.fn(); const setGeneratedCustomWorldProfile = vi.fn(); const executePublishWorld = vi.fn(async () => buildSession()); const syncAgentCreationResultView = vi.fn(); const syncAgentDraftResultProfile = vi.fn(async () => ({ profile: resultProfile, view: null, })); function Harness() { const { enterWorldForTestFromCurrentResult } = useRpgCreationEnterWorld({ isAgentDraftResultView: true, activeAgentSessionId: 'session-1', generatedCustomWorldProfile: resultProfile, handleCustomWorldSelect, syncAgentDraftResultProfile, executePublishWorld, syncAgentCreationResultView, setGeneratedCustomWorldProfile, }); return ( ); } const { getByText } = render(); await act(async () => { getByText('进入').click(); }); expect(executePublishWorld).not.toHaveBeenCalled(); expect(handleCustomWorldSelect).toHaveBeenCalledWith(resultProfile, { mode: 'play', disablePersistence: true, returnStage: 'custom-world-result', }); expect(setGeneratedCustomWorldProfile).toHaveBeenCalledWith(resultProfile); expect( handleCustomWorldSelect.mock.calls[0]?.[0].playableNpcs[0]?.imageSrc, ).toBe('/generated-characters/draft-role/portrait.png'); }); });