收口创作流程统一总计划并修复等待页窄屏裁切
This commit is contained in:
212
src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx
Normal file
212
src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx
Normal file
@@ -0,0 +1,212 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import type {
|
||||
JumpHopRuntimeRunSnapshotResponse,
|
||||
JumpHopWorkProfileResponse,
|
||||
} from '../../../packages/shared/src/contracts/jumpHop';
|
||||
import { JumpHopRuntimeShell } from './JumpHopRuntimeShell';
|
||||
|
||||
const profile: JumpHopWorkProfileResponse = {
|
||||
summary: {
|
||||
runtimeKind: 'jump-hop',
|
||||
workId: 'work-1',
|
||||
profileId: 'profile-1',
|
||||
ownerUserId: 'user-1',
|
||||
sourceSessionId: 'session-1',
|
||||
workTitle: '云端跳台',
|
||||
workDescription: '一路跳到星星。',
|
||||
themeTags: ['云朵'],
|
||||
difficulty: 'standard',
|
||||
stylePreset: 'paper-toy',
|
||||
coverImageSrc: 'data:image/png;base64,cover',
|
||||
publicationStatus: 'draft',
|
||||
playCount: 0,
|
||||
updatedAt: '2026-05-30T10:00:00.000Z',
|
||||
publishedAt: null,
|
||||
publishReady: true,
|
||||
generationStatus: 'ready',
|
||||
},
|
||||
draft: {
|
||||
templateId: 'jump-hop',
|
||||
templateName: '跳一跳',
|
||||
profileId: 'profile-1',
|
||||
workTitle: '云端跳台',
|
||||
workDescription: '一路跳到星星。',
|
||||
themeTags: ['云朵'],
|
||||
difficulty: 'standard',
|
||||
stylePreset: 'paper-toy',
|
||||
characterPrompt: '纸片小兔',
|
||||
tilePrompt: '云朵平台',
|
||||
endMoodPrompt: '星光门',
|
||||
characterAsset: {
|
||||
assetId: 'character-1',
|
||||
imageSrc: 'data:image/png;base64,character',
|
||||
imageObjectKey: 'jump-hop/character.png',
|
||||
assetObjectId: 'asset-character',
|
||||
generationProvider: 'vector-engine-gpt-image-2',
|
||||
prompt: '角色图',
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
},
|
||||
tileAtlasAsset: {
|
||||
assetId: 'tiles-1',
|
||||
imageSrc: 'data:image/png;base64,tiles',
|
||||
imageObjectKey: 'jump-hop/tiles.png',
|
||||
assetObjectId: 'asset-tiles',
|
||||
generationProvider: 'vector-engine-gpt-image-2',
|
||||
prompt: '地块图',
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
},
|
||||
tileAssets: [
|
||||
{
|
||||
tileType: 'start',
|
||||
imageSrc: 'data:image/png;base64,tile-start',
|
||||
imageObjectKey: 'jump-hop/tile-start.png',
|
||||
assetObjectId: 'asset-tile-start',
|
||||
sourceAtlasCell: 'A1',
|
||||
visualWidth: 128,
|
||||
visualHeight: 96,
|
||||
topSurfaceRadius: 24,
|
||||
landingRadius: 28,
|
||||
},
|
||||
],
|
||||
path: {
|
||||
seed: 'jump-hop-seed',
|
||||
difficulty: 'standard',
|
||||
platforms: [
|
||||
{
|
||||
platformId: 'platform-1',
|
||||
tileType: 'start',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 48,
|
||||
height: 36,
|
||||
landingRadius: 22,
|
||||
perfectRadius: 12,
|
||||
scoreValue: 1,
|
||||
},
|
||||
],
|
||||
finishIndex: 0,
|
||||
cameraPreset: 'default',
|
||||
scoring: {
|
||||
chargeToDistanceRatio: 1.2,
|
||||
maxChargeMs: 1800,
|
||||
hitBonus: 20,
|
||||
perfectBonus: 50,
|
||||
},
|
||||
},
|
||||
coverComposite: 'data:image/png;base64,cover',
|
||||
generationStatus: 'ready',
|
||||
},
|
||||
path: {
|
||||
seed: 'jump-hop-seed',
|
||||
difficulty: 'standard',
|
||||
platforms: [
|
||||
{
|
||||
platformId: 'platform-1',
|
||||
tileType: 'start',
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 48,
|
||||
height: 36,
|
||||
landingRadius: 22,
|
||||
perfectRadius: 12,
|
||||
scoreValue: 1,
|
||||
},
|
||||
],
|
||||
finishIndex: 0,
|
||||
cameraPreset: 'default',
|
||||
scoring: {
|
||||
chargeToDistanceRatio: 1.2,
|
||||
maxChargeMs: 1800,
|
||||
hitBonus: 20,
|
||||
perfectBonus: 50,
|
||||
},
|
||||
},
|
||||
characterAsset: {
|
||||
assetId: 'character-1',
|
||||
imageSrc: 'data:image/png;base64,character',
|
||||
imageObjectKey: 'jump-hop/character.png',
|
||||
assetObjectId: 'asset-character',
|
||||
generationProvider: 'vector-engine-gpt-image-2',
|
||||
prompt: '角色图',
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
},
|
||||
tileAtlasAsset: {
|
||||
assetId: 'tiles-1',
|
||||
imageSrc: 'data:image/png;base64,tiles',
|
||||
imageObjectKey: 'jump-hop/tiles.png',
|
||||
assetObjectId: 'asset-tiles',
|
||||
generationProvider: 'vector-engine-gpt-image-2',
|
||||
prompt: '地块图',
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
},
|
||||
tileAssets: [
|
||||
{
|
||||
tileType: 'start',
|
||||
imageSrc: 'data:image/png;base64,tile-start',
|
||||
imageObjectKey: 'jump-hop/tile-start.png',
|
||||
assetObjectId: 'asset-tile-start',
|
||||
sourceAtlasCell: 'A1',
|
||||
visualWidth: 128,
|
||||
visualHeight: 96,
|
||||
topSurfaceRadius: 24,
|
||||
landingRadius: 28,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const run: JumpHopRuntimeRunSnapshotResponse = {
|
||||
runId: 'run-1',
|
||||
profileId: 'profile-1',
|
||||
ownerUserId: 'user-1',
|
||||
status: 'playing',
|
||||
currentPlatformIndex: 0,
|
||||
score: 0,
|
||||
combo: 0,
|
||||
path: profile.path,
|
||||
lastJump: null,
|
||||
startedAtMs: 1000,
|
||||
finishedAtMs: null,
|
||||
};
|
||||
|
||||
test('jump hop runtime shell supports jump, restart and exit actions', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onJump = vi.fn().mockResolvedValue(undefined);
|
||||
const onRestart = vi.fn();
|
||||
const onExit = vi.fn();
|
||||
|
||||
render(
|
||||
<JumpHopRuntimeShell
|
||||
profile={profile}
|
||||
run={run}
|
||||
onJump={onJump}
|
||||
onRestart={onRestart}
|
||||
onExit={onExit}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.pointer([
|
||||
{ target: screen.getByRole('button', { name: '起跳' }), keys: '[MouseLeft>]' },
|
||||
]);
|
||||
await user.pointer([
|
||||
{ target: screen.getByRole('button', { name: '起跳' }), keys: '[/MouseLeft]' },
|
||||
]);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onJump).toHaveBeenCalledWith({ chargeMs: expect.any(Number) });
|
||||
});
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '重开' }));
|
||||
await user.click(screen.getByRole('button', { name: '返回' }));
|
||||
|
||||
expect(onRestart).toHaveBeenCalledTimes(1);
|
||||
expect(onExit).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
Reference in New Issue
Block a user