@@ -0,0 +1,153 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { useState } from 'react';
|
||||
import { beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import type { CustomWorldAgentSessionSnapshot } from '../../../packages/shared/src/contracts/customWorldAgent';
|
||||
import {
|
||||
createCustomWorldAgentSession,
|
||||
getCustomWorldAgentSession,
|
||||
} from '../../services/aiService';
|
||||
import {
|
||||
listCustomWorldGallery,
|
||||
listCustomWorldLibrary,
|
||||
} from '../../services/storageService';
|
||||
import type { GameState } from '../../types';
|
||||
import {
|
||||
PreGameSelectionFlow,
|
||||
type SelectionStage,
|
||||
} from './PreGameSelectionFlow';
|
||||
|
||||
vi.mock('../../services/aiService', () => ({
|
||||
createCustomWorldAgentSession: vi.fn(),
|
||||
executeCustomWorldAgentAction: vi.fn(),
|
||||
generateCustomWorldProfile: vi.fn(),
|
||||
getCustomWorldAgentOperation: vi.fn(),
|
||||
getCustomWorldAgentSession: vi.fn(),
|
||||
sendCustomWorldAgentMessage: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('../../services/storageService', () => ({
|
||||
getCustomWorldGalleryDetail: vi.fn(),
|
||||
listCustomWorldGallery: vi.fn(),
|
||||
listCustomWorldLibrary: vi.fn(),
|
||||
publishCustomWorldProfile: vi.fn(),
|
||||
unpublishCustomWorldProfile: vi.fn(),
|
||||
upsertCustomWorldProfile: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('../custom-world-agent/CustomWorldAgentWorkspace', () => ({
|
||||
CustomWorldAgentWorkspace: ({
|
||||
session,
|
||||
}: {
|
||||
session: CustomWorldAgentSessionSnapshot | null;
|
||||
}) => (
|
||||
<div className="agent-workspace-mock">
|
||||
Agent工作区:{session?.sessionId ?? 'missing-session'}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
||||
const mockSession: CustomWorldAgentSessionSnapshot = {
|
||||
sessionId: 'custom-world-agent-session-1',
|
||||
stage: 'clarifying',
|
||||
focusCardId: null,
|
||||
creatorIntent: {},
|
||||
creatorIntentReadiness: {
|
||||
isReady: false,
|
||||
completedKeys: ['world_hook'],
|
||||
missingKeys: [
|
||||
'player_premise',
|
||||
'theme_and_tone',
|
||||
'core_conflict',
|
||||
'relationship_seed',
|
||||
'iconic_element',
|
||||
],
|
||||
},
|
||||
anchorPack: {},
|
||||
lockState: {},
|
||||
draftProfile: null,
|
||||
messages: [
|
||||
{
|
||||
id: 'message-1',
|
||||
role: 'assistant',
|
||||
kind: 'summary',
|
||||
text: '先告诉我你想做一个怎样的 RPG 世界。',
|
||||
createdAt: '2026-04-14T12:00:00.000Z',
|
||||
relatedOperationId: null,
|
||||
},
|
||||
],
|
||||
draftCards: [],
|
||||
pendingClarifications: [],
|
||||
suggestedActions: [],
|
||||
recommendedReplies: [],
|
||||
qualityFindings: [],
|
||||
assetCoverage: {
|
||||
roleAssets: [],
|
||||
sceneAssets: [],
|
||||
allRoleAssetsReady: false,
|
||||
allSceneAssetsReady: false,
|
||||
},
|
||||
updatedAt: '2026-04-14T12:00:00.000Z',
|
||||
};
|
||||
|
||||
function TestWrapper() {
|
||||
const [selectionStage, setSelectionStage] =
|
||||
useState<SelectionStage>('platform');
|
||||
|
||||
return (
|
||||
<PreGameSelectionFlow
|
||||
selectionStage={selectionStage}
|
||||
setSelectionStage={setSelectionStage}
|
||||
gameState={{} as GameState}
|
||||
hasSavedGame={false}
|
||||
savedSnapshot={null}
|
||||
handleContinueGame={() => {}}
|
||||
handleStartNewGame={() => {}}
|
||||
handleCustomWorldSelect={() => {}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
window.history.replaceState(null, '', '/');
|
||||
window.sessionStorage.clear();
|
||||
vi.mocked(listCustomWorldLibrary).mockResolvedValue([]);
|
||||
vi.mocked(listCustomWorldGallery).mockResolvedValue([]);
|
||||
vi.mocked(createCustomWorldAgentSession).mockResolvedValue({
|
||||
session: mockSession,
|
||||
});
|
||||
vi.mocked(getCustomWorldAgentSession).mockResolvedValue(mockSession);
|
||||
});
|
||||
|
||||
test('create tab opens game type modal, keeps AIRP and visual novel locked, and enters agent workspace for RPG', async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<TestWrapper />);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '创作' }));
|
||||
await user.click(screen.getByRole('button', { name: /开启新的创作/u }));
|
||||
|
||||
expect(screen.getByText('选择创作类型')).toBeTruthy();
|
||||
|
||||
const airpButton = screen.getByRole('button', { name: /AIRP/u });
|
||||
const visualNovelButton = screen.getByRole('button', {
|
||||
name: /视觉小说/u,
|
||||
});
|
||||
|
||||
expect((airpButton as HTMLButtonElement).disabled).toBe(true);
|
||||
expect((visualNovelButton as HTMLButtonElement).disabled).toBe(true);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /角色扮演 RPG/u }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createCustomWorldAgentSession).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
expect(
|
||||
await screen.findByText('Agent工作区:custom-world-agent-session-1'),
|
||||
).toBeTruthy();
|
||||
});
|
||||
Reference in New Issue
Block a user