fix: 优化跳一跳运行态与地块资源

This commit is contained in:
2026-06-09 01:28:30 +08:00
parent c9c66f046b
commit a0473771f1
30 changed files with 3180 additions and 1010 deletions

View File

@@ -1695,6 +1695,28 @@ function buildMockJumpHopWork(
};
}
function buildMockJumpHopRuntimeRun(
work: JumpHopWorkProfileResponse,
overrides: Partial<JumpHopRuntimeRunSnapshotResponse> = {},
): JumpHopRuntimeRunSnapshotResponse {
return {
runId: 'jump-hop-run-1',
profileId: work.summary.profileId,
ownerUserId: work.summary.ownerUserId,
status: 'playing',
currentPlatformIndex: 0,
successfulJumpCount: 0,
durationMs: 0,
score: 0,
combo: 0,
path: work.path,
lastJump: null,
startedAtMs: 1_779_999_000_000,
finishedAtMs: null,
...overrides,
};
}
function buildMockBarkBattleWork(
overrides: Partial<BarkBattleWorkSummary> = {},
): BarkBattleWorkSummary {
@@ -6937,6 +6959,89 @@ test('logged out public jump-hop detail starts runtime without requireAuth', asy
expect(requireAuth).not.toHaveBeenCalled();
});
test('direct jump hop runtime route without work code returns platform home', async () => {
window.history.replaceState(null, '', '/runtime/jump-hop');
render(<TestWrapper withAuth />);
await waitFor(() => {
expect(window.location.pathname).toBe('/');
});
expect(window.location.search).toBe('');
expect(jumpHopClient.getGalleryDetail).not.toHaveBeenCalled();
expect(jumpHopClient.startRun).not.toHaveBeenCalled();
expect(await screen.findByRole('button', { name: '创作' })).toBeTruthy();
});
test('direct jump hop runtime route with public work code starts published run', async () => {
const publishedJumpHopWork = buildMockJumpHopWork({
summary: {
runtimeKind: 'jump-hop',
workId: 'jump-hop-work-direct-1',
profileId: 'jump-hop-profile-direct-12345678',
ownerUserId: 'user-2',
sourceSessionId: 'jump-hop-session-direct-1',
themeText: '星星果园',
workTitle: '星星果园跳一跳',
workDescription: '沿着水果一路弹跳。',
themeTags: ['果园', '星星'],
difficulty: 'standard',
stylePreset: 'paper-toy',
coverImageSrc: null,
publicationStatus: 'published',
playCount: 8,
updatedAt: '2026-06-07T10:00:00.000Z',
publishedAt: '2026-06-07T10:00:00.000Z',
publishReady: true,
generationStatus: 'ready',
},
});
const publishedJumpHopRun = buildMockJumpHopRuntimeRun(publishedJumpHopWork, {
runId: 'jump-hop-run-direct-1',
ownerUserId: '',
});
window.history.replaceState(null, '', '/runtime/jump-hop?work=JH-12345678');
vi.mocked(jumpHopClient.getGalleryDetail).mockResolvedValue({
item: publishedJumpHopWork,
});
vi.mocked(jumpHopClient.startRun).mockResolvedValue({
run: publishedJumpHopRun,
});
vi.mocked(jumpHopClient.getLeaderboard).mockResolvedValue({
profileId: publishedJumpHopWork.summary.profileId,
items: [],
viewerBest: null,
});
render(
<TestWrapper
authValue={createAuthValue({
user: null,
canAccessProtectedData: false,
openLoginModal: () => {},
requireAuth: vi.fn(),
})}
/>,
);
await waitFor(() => {
expect(jumpHopClient.getGalleryDetail).toHaveBeenCalledWith('JH-12345678');
});
await waitFor(() => {
expect(jumpHopClient.startRun).toHaveBeenCalledWith(
publishedJumpHopWork.summary.profileId,
expect.objectContaining({
runtimeGuestToken: 'runtime-guest-token',
runtimeMode: 'published',
}),
);
});
expect(jumpHopClient.getWorkDetail).not.toHaveBeenCalled();
expect(window.location.pathname).toBe('/runtime/jump-hop');
expect(window.location.search).toContain('work=JH-12345678');
});
test('owned public puzzle detail edits original draft instead of remixing', async () => {
const user = userEvent.setup();
const ownedPuzzleWork = {