完善抓大鹅创作入口与运行态表现
This commit is contained in:
@@ -10,6 +10,9 @@ import type {
|
||||
CustomWorldAgentSessionSnapshot,
|
||||
CustomWorldWorkSummary,
|
||||
} from '../../../packages/shared/src/contracts/customWorldAgent';
|
||||
import type {
|
||||
Match3DAgentSessionSnapshot,
|
||||
} from '../../../packages/shared/src/contracts/match3dAgent';
|
||||
import type { Match3DRunSnapshot } from '../../../packages/shared/src/contracts/match3dRuntime';
|
||||
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
||||
import type { PuzzleRunSnapshot } from '../../../packages/shared/src/contracts/puzzleRuntimeSession';
|
||||
@@ -124,17 +127,6 @@ async function openCreationHub(user: ReturnType<typeof userEvent.setup>) {
|
||||
expect(await screen.findByText('角色扮演')).toBeTruthy();
|
||||
}
|
||||
|
||||
async function expectRpgCreationLocked(
|
||||
user: ReturnType<typeof userEvent.setup>,
|
||||
) {
|
||||
await openCreationHub(user);
|
||||
const rpgButton = screen.getByRole('button', { name: /角色扮演/u });
|
||||
expect((rpgButton as HTMLButtonElement).disabled).toBe(true);
|
||||
expect(within(rpgButton).getAllByText('敬请期待').length).toBeGreaterThan(0);
|
||||
await user.click(rpgButton);
|
||||
expect(createRpgCreationSession).not.toHaveBeenCalled();
|
||||
}
|
||||
|
||||
async function openExistingRpgDraft(
|
||||
user: ReturnType<typeof userEvent.setup>,
|
||||
actionName: string | RegExp = /继续(?:完善|创作)/u,
|
||||
@@ -433,6 +425,21 @@ vi.mock('../big-fish-result/BigFishResultView', () => ({
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock('../match3d-creation/Match3DAgentWorkspace', () => ({
|
||||
Match3DAgentWorkspace: ({
|
||||
session,
|
||||
}: {
|
||||
session: { sessionId: string; messages: Array<{ text: string }> } | null;
|
||||
}) => (
|
||||
<div className="match3d-agent-workspace-mock">
|
||||
<div>抓大鹅工作区:{session?.sessionId ?? 'missing-session'}</div>
|
||||
{session?.messages.map((message) => (
|
||||
<div key={`${session.sessionId}-${message.text}`}>{message.text}</div>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock('../match3d-runtime/Match3DRuntimeShell', () => ({
|
||||
Match3DRuntimeShell: ({
|
||||
run,
|
||||
@@ -670,6 +677,59 @@ function buildMockMatch3DRun(profileId: string): Match3DRunSnapshot {
|
||||
};
|
||||
}
|
||||
|
||||
function buildMockMatch3DAgentSession(
|
||||
overrides: Partial<Match3DAgentSessionSnapshot> = {},
|
||||
): Match3DAgentSessionSnapshot {
|
||||
const sessionId = overrides.sessionId ?? 'match3d-agent-session-1';
|
||||
|
||||
return {
|
||||
sessionId,
|
||||
currentTurn: 0,
|
||||
progressPercent: 20,
|
||||
stage: 'collecting',
|
||||
anchorPack: {
|
||||
theme: {
|
||||
key: 'theme',
|
||||
label: '题材主题',
|
||||
value: '水果消除',
|
||||
status: 'confirmed',
|
||||
},
|
||||
clearCount: {
|
||||
key: 'clearCount',
|
||||
label: '需要消除次数',
|
||||
value: '4',
|
||||
status: 'confirmed',
|
||||
},
|
||||
difficulty: {
|
||||
key: 'difficulty',
|
||||
label: '难度',
|
||||
value: '5',
|
||||
status: 'confirmed',
|
||||
},
|
||||
},
|
||||
config: {
|
||||
themeText: '水果消除',
|
||||
referenceImageSrc: null,
|
||||
clearCount: 4,
|
||||
difficulty: 5,
|
||||
},
|
||||
draft: null,
|
||||
messages: [
|
||||
{
|
||||
id: 'match3d-message-1',
|
||||
role: 'assistant',
|
||||
kind: 'chat',
|
||||
text: '我们先确定抓大鹅题材、消除次数和难度。',
|
||||
createdAt: '2026-05-01T10:00:00.000Z',
|
||||
},
|
||||
],
|
||||
lastAssistantReply: '我们先确定抓大鹅题材、消除次数和难度。',
|
||||
publishedProfileId: null,
|
||||
updatedAt: '2026-05-01T10:00:00.000Z',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function buildMockRpgGalleryDetail(
|
||||
entry: CustomWorldGalleryCard,
|
||||
): CustomWorldLibraryEntry {
|
||||
@@ -2500,6 +2560,38 @@ test('puzzle creation timeout exits busy state and shows a readable error', asyn
|
||||
expect(screen.queryByText(/正在准备拼图共创工作区/u)).toBeNull();
|
||||
});
|
||||
|
||||
test('match3d creation card opens workspace even when public galleries fail', async () => {
|
||||
const user = userEvent.setup();
|
||||
const match3dSession = buildMockMatch3DAgentSession();
|
||||
|
||||
vi.mocked(listRpgEntryWorldGallery).mockRejectedValueOnce(
|
||||
new Error('读取作品广场失败'),
|
||||
);
|
||||
vi.mocked(listMatch3DGallery).mockRejectedValueOnce(
|
||||
new Error('读取抓大鹅广场失败'),
|
||||
);
|
||||
vi.mocked(match3dCreationClient.createSession).mockResolvedValueOnce({
|
||||
session: match3dSession,
|
||||
});
|
||||
|
||||
render(<TestWrapper withAuth />);
|
||||
|
||||
await openCreationHub(user);
|
||||
expect(screen.queryByText('读取作品广场失败')).toBeNull();
|
||||
expect(screen.queryByText('读取抓大鹅广场失败')).toBeNull();
|
||||
|
||||
const button = screen.getByRole('button', {
|
||||
name: /抓大鹅.*经典消除玩法/u,
|
||||
});
|
||||
expect(button as HTMLButtonElement).toHaveProperty('disabled', false);
|
||||
await user.click(button);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(match3dCreationClient.createSession).toHaveBeenCalledWith({});
|
||||
});
|
||||
expect(await screen.findByText('抓大鹅工作区:match3d-agent-session-1')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('puzzle draft card restores the bound agent session and opens the result view', async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user