fix(jump-hop): preserve themed runtime metadata
This commit is contained in:
@@ -283,7 +283,10 @@ pub async fn start_jump_hop_run(
|
||||
) -> Result<Json<Value>, Response> {
|
||||
let Json(payload) = jump_hop_json(payload, &request_context, JUMP_HOP_RUNTIME_PROVIDER)?;
|
||||
ensure_non_empty(&request_context, &payload.profile_id, "profileId")?;
|
||||
let is_draft_runtime = payload.runtime_mode.as_deref() == Some("draft");
|
||||
let is_draft_runtime = payload
|
||||
.runtime_mode
|
||||
.as_deref()
|
||||
.is_some_and(is_jump_hop_draft_runtime_mode);
|
||||
let owner_user_id = principal.subject().to_string();
|
||||
let principal_kind = principal.kind().as_str();
|
||||
let run = state
|
||||
@@ -1240,6 +1243,10 @@ fn build_jump_hop_work_play_tracking_draft(
|
||||
WorkPlayTrackingDraft::runtime_principal("jump-hop", work_id, principal, source_route)
|
||||
}
|
||||
|
||||
fn is_jump_hop_draft_runtime_mode(runtime_mode: &str) -> bool {
|
||||
runtime_mode.trim().eq_ignore_ascii_case("draft")
|
||||
}
|
||||
|
||||
fn build_jump_hop_draft(payload: &JumpHopWorkspaceCreateRequest) -> JumpHopDraftResponse {
|
||||
let theme_text = normalize_theme_text(&payload.theme_text, &payload.work_title);
|
||||
JumpHopDraftResponse {
|
||||
@@ -1422,6 +1429,14 @@ fn current_utc_micros() -> i64 {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn jump_hop_draft_runtime_mode_detection_matches_client_normalization() {
|
||||
assert!(is_jump_hop_draft_runtime_mode("draft"));
|
||||
assert!(is_jump_hop_draft_runtime_mode(" DRAFT "));
|
||||
assert!(!is_jump_hop_draft_runtime_mode("published"));
|
||||
assert!(!is_jump_hop_draft_runtime_mode(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jump_hop_tile_atlas_prompt_uses_dedicated_five_by_five_floor_layout() {
|
||||
let prompt = build_jump_hop_tile_atlas_prompt("森林冒险", "森林主题清爽游戏化立体感平台");
|
||||
|
||||
@@ -37,3 +37,93 @@ test('jump hop creation keeps image2 generation requests alive long enough', asy
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
test('jump hop work detail preserves flattened back button asset', async () => {
|
||||
const backButtonAsset = {
|
||||
assetId: 'back-button-1',
|
||||
imageSrc: '/generated-jump-hop-assets/back-button-1.png',
|
||||
imageObjectKey: 'jump-hop/back-button-1.png',
|
||||
assetObjectId: 'asset-object-back-button-1',
|
||||
generationProvider: 'image2',
|
||||
prompt: '主题返回按钮',
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
};
|
||||
const characterAsset = {
|
||||
assetId: 'character-1',
|
||||
imageSrc: 'builtin://jump-hop/default-character',
|
||||
imageObjectKey: '',
|
||||
assetObjectId: 'character-object-1',
|
||||
generationProvider: 'builtin-three',
|
||||
prompt: '内置默认角色',
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
const draft = {
|
||||
templateId: 'jump-hop',
|
||||
templateName: '跳一跳',
|
||||
profileId: 'profile-1',
|
||||
themeText: '森林茶馆',
|
||||
workTitle: '森林茶馆跳一跳',
|
||||
workDescription: '森林茶馆主题',
|
||||
themeTags: ['森林茶馆', '跳一跳'],
|
||||
difficulty: 'standard',
|
||||
stylePreset: 'minimal-blocks',
|
||||
defaultCharacter: null,
|
||||
characterPrompt: '内置默认角色',
|
||||
tilePrompt: '森林茶馆主题地块',
|
||||
endMoodPrompt: null,
|
||||
characterAsset,
|
||||
tileAtlasAsset: characterAsset,
|
||||
tileAssets: [],
|
||||
path: {
|
||||
seed: 'profile-1',
|
||||
difficulty: 'standard',
|
||||
platforms: [],
|
||||
scoring: {
|
||||
perfectRadiusRatio: 0.24,
|
||||
hitRadiusRatio: 0.52,
|
||||
maxChargeMs: 1200,
|
||||
minChargeMs: 80,
|
||||
maxJumpDistance: 5,
|
||||
},
|
||||
},
|
||||
coverComposite: null,
|
||||
backButtonAsset: null,
|
||||
generationStatus: 'ready',
|
||||
};
|
||||
requestJsonMock.mockResolvedValue({
|
||||
item: {
|
||||
runtimeKind: 'jump-hop',
|
||||
workId: 'work-1',
|
||||
profileId: 'profile-1',
|
||||
ownerUserId: 'owner-1',
|
||||
sourceSessionId: 'session-1',
|
||||
themeText: '森林茶馆',
|
||||
workTitle: '森林茶馆跳一跳',
|
||||
workDescription: '森林茶馆主题',
|
||||
themeTags: ['森林茶馆', '跳一跳'],
|
||||
difficulty: 'standard',
|
||||
stylePreset: 'minimal-blocks',
|
||||
coverImageSrc: null,
|
||||
publicationStatus: 'published',
|
||||
playCount: 0,
|
||||
updatedAt: '2026-06-05T00:00:00Z',
|
||||
publishedAt: '2026-06-05T00:00:00Z',
|
||||
publishReady: true,
|
||||
generationStatus: 'ready',
|
||||
draft,
|
||||
path: draft.path,
|
||||
defaultCharacter: null,
|
||||
characterAsset,
|
||||
tileAtlasAsset: characterAsset,
|
||||
tileAssets: [],
|
||||
backButtonAsset,
|
||||
},
|
||||
});
|
||||
|
||||
const { jumpHopClient } = await import('./jumpHopClient');
|
||||
const response = await jumpHopClient.getWorkDetail('profile-1');
|
||||
|
||||
expect(response.item.backButtonAsset).toEqual(backButtonAsset);
|
||||
});
|
||||
|
||||
@@ -136,6 +136,8 @@ function normalizeJumpHopWorkProfile(
|
||||
characterAsset: flattened.characterAsset,
|
||||
tileAtlasAsset: flattened.tileAtlasAsset,
|
||||
tileAssets: flattened.tileAssets,
|
||||
backButtonAsset:
|
||||
flattened.backButtonAsset ?? flattened.draft?.backButtonAsset ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user