159 lines
4.5 KiB
TypeScript
159 lines
4.5 KiB
TypeScript
/** @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 { WorldType, type CustomWorldProfile } 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 草稿进入游戏时使用 session draft profile 的角色形象', async () => {
|
|
const staleResultProfile = buildProfile({
|
|
id: 'stale-result',
|
|
name: '旧结果页快照',
|
|
imageSrc: '/template/old-role.png',
|
|
});
|
|
const draftProfile = 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());
|
|
|
|
function Harness() {
|
|
const { enterWorldForTestFromCurrentResult } = useRpgCreationEnterWorld({
|
|
isAgentDraftResultView: true,
|
|
activeAgentSessionId: 'session-1',
|
|
generatedCustomWorldProfile: staleResultProfile,
|
|
agentSessionProfile: draftProfile,
|
|
agentSession: buildSession(),
|
|
handleCustomWorldSelect,
|
|
executePublishWorld,
|
|
setGeneratedCustomWorldProfile,
|
|
});
|
|
|
|
return (
|
|
<button type="button" onClick={() => void enterWorldForTestFromCurrentResult()}>
|
|
进入
|
|
</button>
|
|
);
|
|
}
|
|
|
|
const { getByText } = render(<Harness />);
|
|
await act(async () => {
|
|
getByText('进入').click();
|
|
});
|
|
|
|
expect(executePublishWorld).not.toHaveBeenCalled();
|
|
expect(handleCustomWorldSelect).toHaveBeenCalledWith(draftProfile);
|
|
expect(handleCustomWorldSelect.mock.calls[0]?.[0].playableNpcs[0]?.imageSrc).toBe(
|
|
'/generated-characters/draft-role/portrait.png',
|
|
);
|
|
});
|
|
});
|