From 925aefd93451ee0c4f0bf168350ead8012d4e648 Mon Sep 17 00:00:00 2001 From: kdletters Date: Wed, 19 Aug 2026 14:42:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAGC=20Native=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=A4=B9=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 固定普通 JSON Provider mock 为非流式 为平台账号画布与视觉门禁测试安装隔离会话 同步现役路由、默认配置与提示词断言 --- .../src-tauri/src/agent/generation/tests.rs | 8 ++- .../src/tests/collaboration/delegation.rs | 17 ++++- .../tests/collaboration/static_deliveries.rs | 12 +++- .../src-tauri/src/tests/configuration.rs | 2 +- .../src-tauri/src/tests/mod.rs | 63 +++++++++++++++++-- .../src-tauri/src/tests/project.rs | 45 ++++++++++--- .../src-tauri/src/tests/provider.rs | 1 + .../src-tauri/src/tests/response_stream.rs | 5 ++ .../tests/runtime_actions/action_execution.rs | 5 ++ .../planning_strategy/autonomous_build.rs | 6 +- .../src-tauri/src/tests/runtime_state.rs | 5 ++ 11 files changed, 151 insertions(+), 18 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/tests.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/tests.rs index 31381a004..5b82b57ad 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/tests.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/tests.rs @@ -7,7 +7,13 @@ pub(crate) async fn request_llm_game_draft_with_client( short_memory: &str, long_memory: &str, ) -> Result { - let llm = GameCreatorLlmConfig::default(); + // This helper exercises the one-shot OpenAI-compatible response fixture. + // Streaming has its own response-stream coverage; keeping this explicit + // prevents the production default from making the mock parse JSON as SSE. + let llm = GameCreatorLlmConfig { + stream: false, + ..GameCreatorLlmConfig::default() + }; request_generator_game_draft_with_client( client, &llm, diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs index 13ce2dca3..a4e05512f 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs @@ -1217,6 +1217,11 @@ async fn visual_specialists_reject_overriding_their_fixed_image_contract() { #[test] fn design_foundation_rejects_scene_image_stale_run_and_stale_sha_visual_proofs() { + let _platform_session = crate::platform_session::install_test_platform_session( + "visual-semantic-gate-test-user", + "visual-semantic-gate-test-key", + "https://dev.genarrative.world", + ); let _config_guard = crate::tests::write_test_local_config( r#"{"editorApi":{"apiKey":"visual-semantic-gate-test-key"}}"#.to_string(), ); @@ -1608,6 +1613,11 @@ async fn canvas_replacement_rejects_parent_run_that_terminates_during_external_r request_sender, generation_release_receiver, ); + let _platform_session = crate::platform_session::install_test_platform_session( + "canvas-replacement-user", + "editor-runtime-key", + &canvas_base_url, + ); init_local_game_project_at(&root, "project-canvas-repair-atomic", "月光厨房") .expect("project init"); register_canvas_visual_asset_fixture(&root, "assets/art-spec.png", "icon-spec"); @@ -1800,7 +1810,7 @@ async fn canvas_replacement_rejects_parent_run_that_terminates_during_external_r let captured = request_receiver .recv_timeout(Duration::from_secs(15)) .expect("canvas request before generation response"); - if captured.starts_with("POST /api/external/v1/editor/icon-spritesheets/generations ") { + if captured.starts_with("POST /api/editor/icon-spritesheets/generations ") { saw_generation_request = true; break; } @@ -2231,6 +2241,11 @@ fn gui_and_cli_autonomous_runs_still_allow_publish_delegates() { #[test] fn visual_specialist_delegations_require_image_artifacts_but_read_only_work_allows_none() { + let _platform_session = crate::platform_session::install_test_platform_session( + "visual-delegation-contract-user", + "visual-delegation-contract-key", + "https://dev.genarrative.world", + ); let _config_guard = crate::tests::write_test_local_config( r#"{"editorApi":{"apiKey":"visual-delegation-contract-key"}}"#.to_string(), ); diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/static_deliveries.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/static_deliveries.rs index 0a9f01982..b7bcbf461 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/static_deliveries.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/static_deliveries.rs @@ -38,6 +38,11 @@ fn project_supervisor_runtime_id_is_normalized_and_collected() { #[test] fn visual_specialist_prompts_require_real_registered_image_deliveries() { + let _platform_session = crate::platform_session::install_test_platform_session( + "visual-prompt-test-user", + "visual-prompt-test-key", + "https://dev.genarrative.world", + ); let _config_guard = crate::tests::write_test_local_config( r#"{"editorApi":{"apiKey":"visual-prompt-test-key"}}"#.to_string(), ); @@ -154,6 +159,11 @@ fn visual_prompts_degrade_to_text_contracts_without_editor_api_key() { #[tokio::test] async fn project_supervisor_prompts_are_total_control_and_reject_isolated_template() { let planning_prompt = { + let _platform_session = crate::platform_session::install_test_platform_session( + "supervisor-prompt-test-user", + "supervisor-prompt-test-key", + "https://dev.genarrative.world", + ); let _config_guard = crate::tests::write_test_local_config( r#"{"editorApi":{"apiKey":"supervisor-prompt-test-key"}}"#.to_string(), ); @@ -307,7 +317,7 @@ fn project_supervisor_llm_config_prefers_specific_patch_and_falls_back_to_legacy assert_eq!(specialist.api_key, "global-key"); assert_eq!(specialist.base_url, "https://global.example.test/v1"); assert_eq!(specialist.model, "global-model"); - assert!(!specialist.stream); + assert!(specialist.stream); } #[test] diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/configuration.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/configuration.rs index 0ef277145..b4763f598 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/configuration.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/configuration.rs @@ -531,7 +531,7 @@ fn runtime_config_read_returns_defaults_when_file_is_missing() { result.config.llm.reasoning_effort, DEFAULT_GAME_CREATOR_LLM_REASONING_EFFORT ); - assert!(!result.config.llm.stream); + assert!(result.config.llm.stream); assert!(!result.config.llm.web_search_enabled); assert_eq!( result.config.llm.context_window_tokens, diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs index 642927481..e936da8ad 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs @@ -1230,6 +1230,14 @@ pub(crate) fn write_test_local_config(content: String) -> TestConfigGuard { config .entry("agentMode") .or_insert_with(|| serde_json::json!(GAME_CREATOR_AGENT_MODE_PROVIDER)); + let llm = config.entry("llm").or_insert_with(|| serde_json::json!({})); + if !llm.is_object() { + *llm = serde_json::json!({}); + } + llm.as_object_mut() + .expect("test config LLM value must be an object") + .entry("stream") + .or_insert_with(|| serde_json::json!(false)); } serde_json::to_vec_pretty(&config).expect("serialize explicit Provider test config") } @@ -1243,6 +1251,27 @@ pub(crate) fn write_test_local_config(content: String) -> TestConfigGuard { } } +#[test] +fn test_local_config_defaults_mock_provider_to_non_streaming_and_preserves_explicit_stream() { + let guard = + write_test_local_config(r#"{"agentMode":"codex_cli","llm":{"stream":true}}"#.to_string()); + let explicit_stream = serde_json::from_slice::( + &fs::read(test_local_config_path()).expect("read explicit streaming test config"), + ) + .expect("parse explicit streaming test config"); + assert_eq!(explicit_stream["agentMode"], "codex_cli"); + assert_eq!(explicit_stream["llm"]["stream"], true); + drop(guard); + + let _guard = write_test_local_config(r#"{"agentLlm":{}}"#.to_string()); + let defaulted = serde_json::from_slice::( + &fs::read(test_local_config_path()).expect("read defaulted mock provider test config"), + ) + .expect("parse defaulted mock provider test config"); + assert_eq!(defaulted["agentMode"], GAME_CREATOR_AGENT_MODE_PROVIDER); + assert_eq!(defaulted["llm"]["stream"], false); +} + fn use_test_runtime_config_dir(path: PathBuf) -> TestRuntimeConfigDirGuard { let lock = TEST_CONFIG_LOCK .lock() @@ -3103,17 +3132,23 @@ fn spawn_mock_external_canvas_api_server_with_capture_and_generation_gate( let normalized_request = request.to_ascii_lowercase(); let (status, content_type, body) = if request .starts_with("GET /api/external/v1/editor/projects ") + || request.starts_with("GET /api/editor/projects ") { assert!(normalized_request.contains("authorization: bearer ")); ("200 OK", "application/json", projects_body.as_bytes().to_vec()) - } else if request.starts_with("GET /api/external/v1/editor/assets/library ") { + } else if request.starts_with("GET /api/external/v1/editor/assets/library ") + || request.starts_with("GET /api/editor/assets/library ") + { assert!(normalized_request.contains("authorization: bearer ")); ("200 OK", "application/json", library_body.as_bytes().to_vec()) } else if request.starts_with("GET /api/external/v1/editor/projects/canvas-project-1 ") + || request.starts_with("GET /api/editor/projects/canvas-project-1 ") { assert!(normalized_request.contains("authorization: bearer ")); ("200 OK", "application/json", project_body.as_bytes().to_vec()) - } else if request.starts_with("POST /api/external/v1/editor/images/generations ") { + } else if request.starts_with("POST /api/external/v1/editor/images/generations ") + || request.starts_with("POST /api/editor/images/generations ") + { assert!(normalized_request.contains("authorization: bearer ")); let idempotency_key = request .lines() @@ -3134,6 +3169,7 @@ fn spawn_mock_external_canvas_api_server_with_capture_and_generation_gate( ) } else if request .starts_with("POST /api/external/v1/editor/icon-spritesheets/generations ") + || request.starts_with("POST /api/editor/icon-spritesheets/generations ") { assert!(normalized_request.contains("authorization: bearer ")); let idempotency_key = request @@ -3155,6 +3191,8 @@ fn spawn_mock_external_canvas_api_server_with_capture_and_generation_gate( ) } else if request.starts_with( "GET /api/external/v1/generations/task-external-fixture-1 ", + ) || request.starts_with( + "GET /api/runtime/external-generation/jobs/task-external-fixture-1 ", ) { assert!(normalized_request.contains("authorization: bearer ")); if let Some(gate) = generation_response_gate.take() { @@ -3196,11 +3234,15 @@ fn spawn_mock_external_canvas_api_server_with_capture_and_generation_gate( ) } else if request.starts_with( "GET /api/external/v1/assets/read-url?objectKey=generated%2Fcanvas%2Fhero.png ", + ) || request.starts_with( + "GET /api/assets/read-url?objectKey=generated%2Fcanvas%2Fhero.png ", ) { assert!(normalized_request.contains("authorization: bearer ")); ("200 OK", "application/json", read_body.as_bytes().to_vec()) } else if request.starts_with( "GET /api/external/v1/assets/read-url?objectKey=generated%2Fcanvas%2Fspritesheet.png ", + ) || request.starts_with( + "GET /api/assets/read-url?objectKey=generated%2Fcanvas%2Fspritesheet.png ", ) { assert!(normalized_request.contains("authorization: bearer ")); ( @@ -3211,6 +3253,8 @@ fn spawn_mock_external_canvas_api_server_with_capture_and_generation_gate( } else if let Some(index) = (0..4).find(|index| { request.starts_with(&format!( "GET /api/external/v1/assets/read-url?objectKey=generated%2Fcanvas%2Fspritesheet-slice-{index}.png " + )) || request.starts_with(&format!( + "GET /api/assets/read-url?objectKey=generated%2Fcanvas%2Fspritesheet-slice-{index}.png " )) }) { assert!(normalized_request.contains("authorization: bearer ")); @@ -3285,7 +3329,10 @@ fn spawn_mock_external_canvas_generation_failure_server() -> String { .contains("authorization: bearer ")); let (status, body) = match index { 0 => { - assert!(request.starts_with("GET /api/external/v1/editor/projects ")); + assert!( + request.starts_with("GET /api/external/v1/editor/projects ") + || request.starts_with("GET /api/editor/projects ") + ); ( "200 OK", serde_json::json!({ @@ -3298,7 +3345,10 @@ fn spawn_mock_external_canvas_generation_failure_server() -> String { ) } 1 => { - assert!(request.starts_with("GET /api/external/v1/editor/assets/library ")); + assert!( + request.starts_with("GET /api/external/v1/editor/assets/library ") + || request.starts_with("GET /api/editor/assets/library ") + ); ( "200 OK", serde_json::json!({ @@ -3311,7 +3361,10 @@ fn spawn_mock_external_canvas_generation_failure_server() -> String { ) } _ => { - assert!(request.starts_with("POST /api/external/v1/editor/images/generations ")); + assert!( + request.starts_with("POST /api/external/v1/editor/images/generations ") + || request.starts_with("POST /api/editor/images/generations ") + ); ( "500 Internal Server Error", "{\"error\":\"generation failed\"}".to_string(), diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs index 7a3f581b2..671ac80ed 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/project.rs @@ -651,6 +651,11 @@ async fn background_agent_runtime_can_generate_platform_art_asset() { let config_dir = unique_project_path(); let (canvas_sender, canvas_receiver) = mpsc::channel(); let canvas_base_url = spawn_mock_external_canvas_generation_api_server(Some(canvas_sender)); + let _platform_session = crate::platform_session::install_test_platform_session( + "background-art-user", + "editor-runtime-key", + &canvas_base_url, + ); init_local_game_project_at(&root, "project-1", "月光厨房").expect("project init"); register_canvas_visual_asset_fixture(&root, "assets/art-spec.png", "icon-spec"); write_project_permission_policy_at( @@ -688,6 +693,7 @@ async fn background_agent_runtime_can_generate_platform_art_asset() { config_dir.join(GAME_CREATOR_CONFIG_FILE_NAME), serde_json::json!({ "agentMode": "provider", + "llm": { "stream": false }, "editorApi": { "baseUrl": canvas_base_url, "apiKey": "editor-runtime-key" @@ -835,14 +841,12 @@ async fn background_agent_runtime_can_generate_platform_art_asset() { .collect::>(); let generation_request = canvas_requests .iter() - .find(|request| { - request.starts_with("POST /api/external/v1/editor/icon-spritesheets/generations ") - }) + .find(|request| request.starts_with("POST /api/editor/icon-spritesheets/generations ")) .expect("canvas generation request"); assert_eq!( canvas_requests .iter() - .filter(|request| request.starts_with("POST /api/external/v1/editor/")) + .filter(|request| request.starts_with("POST /api/editor/")) .count(), 1, "queued/running polling must not submit generation again" @@ -850,7 +854,7 @@ async fn background_agent_runtime_can_generate_platform_art_asset() { assert_eq!( canvas_requests .iter() - .filter(|request| request.starts_with("GET /api/external/v1/generations/")) + .filter(|request| request.starts_with("GET /api/runtime/external-generation/jobs/")) .count(), 3, "fixture should exercise queued, running, and completed states" @@ -889,6 +893,11 @@ async fn canonical_art_spec_and_ui_requests_use_the_shared_reference_chain() { let (request_sender, request_receiver) = mpsc::channel(); let canvas_base_url = spawn_mock_external_canvas_generation_api_server(Some(request_sender)); + let _platform_session = crate::platform_session::install_test_platform_session( + "canonical-art-user", + "editor-runtime-key", + &canvas_base_url, + ); fs::create_dir_all(config_dir).expect("create runtime config dir"); fs::write( config_dir.join(GAME_CREATOR_CONFIG_FILE_NAME), @@ -938,7 +947,7 @@ async fn canonical_art_spec_and_ui_requests_use_the_shared_reference_chain() { }, ) .await; - assert!(spec_request.starts_with("POST /api/external/v1/editor/images/generations ")); + assert!(spec_request.starts_with("POST /api/editor/images/generations ")); assert!(spec_request.contains(r#""kind":"spec""#)); assert!(spec_request.contains(r#""assetKind":"icon-spec""#)); assert!(spec_request.contains(r#""referenceImageSrcs":[]"#)); @@ -958,7 +967,7 @@ async fn canonical_art_spec_and_ui_requests_use_the_shared_reference_chain() { }, ) .await; - assert!(ui_request.starts_with("POST /api/external/v1/editor/images/generations ")); + assert!(ui_request.starts_with("POST /api/editor/images/generations ")); assert!(ui_request.contains(r#""kind":"ui-design""#)); assert!(ui_request.contains(r#""referenceImageSrcs":["resource-icon-spec"]"#)); @@ -977,6 +986,11 @@ async fn platform_art_external_request_does_not_hold_project_lock_or_overwrite_m request_sender, generation_release_receiver, ); + let _platform_session = crate::platform_session::install_test_platform_session( + "project-lock-art-user", + "editor-runtime-key", + &canvas_base_url, + ); init_local_game_project_at(&root, "project-canvas-request-lock", "月光厨房") .expect("project init"); register_canvas_visual_asset_fixture(&root, "assets/art-spec.png", "icon-spec"); @@ -1025,7 +1039,7 @@ async fn platform_art_external_request_does_not_hold_project_lock_or_overwrite_m let captured = request_receiver .recv_timeout(Duration::from_secs(15)) .expect("canvas request before generation response"); - if captured.starts_with("POST /api/external/v1/editor/icon-spritesheets/generations ") { + if captured.starts_with("POST /api/editor/icon-spritesheets/generations ") { saw_generation_request = true; break; } @@ -1871,6 +1885,11 @@ fn import_canvas_export_zip_copies_files_and_registers_assets() { async fn sync_canvas_project_assets_downloads_external_resources() { let root = unique_project_path(); let base_url = spawn_mock_external_canvas_api_server(); + let _platform_session = crate::platform_session::install_test_platform_session( + "canvas-sync-user", + "test-editor-api-key", + &base_url, + ); let result = sync_canvas_project_assets_at( &root, @@ -1918,6 +1937,11 @@ async fn generate_platform_art_asset_downloads_and_registers_external_image() { let root = unique_project_path(); let config_dir = unique_project_path(); let base_url = spawn_mock_external_canvas_generation_api_server(None); + let _platform_session = crate::platform_session::install_test_platform_session( + "platform-art-user", + "editor-unit-key", + &base_url, + ); init_local_game_project_at(&root, "project-platform-art", "未命名游戏原型") .expect("project init"); fs::create_dir_all(&config_dir).expect("runtime config dir"); @@ -1998,6 +2022,11 @@ async fn platform_art_generation_step_falls_back_without_leaking_editor_key() { .expect("project init"); let config_dir = unique_project_path(); let base_url = spawn_mock_external_canvas_generation_failure_server(); + let _platform_session = crate::platform_session::install_test_platform_session( + "platform-art-fallback-user", + "editor-fallback-secret", + &base_url, + ); fs::create_dir_all(&config_dir).expect("runtime config dir"); fs::write( config_dir.join(GAME_CREATOR_CONFIG_FILE_NAME), diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/provider.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/provider.rs index e260cb1a2..aab8c3cbc 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/provider.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/provider.rs @@ -6729,6 +6729,7 @@ async fn agent_loop_writes_spec_findings_and_retries_generator() { api_key: "test-key".to_string(), base_url, model: "mock-game-model".to_string(), + stream: false, ..GameCreatorLlmConfig::default() }, ..GameCreatorAppConfig::default() diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/response_stream.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/response_stream.rs index 1eae8af9a..03665afb2 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/response_stream.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/response_stream.rs @@ -982,6 +982,11 @@ async fn provider_retry_final_reply_thinking_only_response_retries_before_handof #[test] fn visual_specialist_finalization_requires_existing_registered_canvas_image() { + let _platform_session = crate::platform_session::install_test_platform_session( + "visual-finalization-test-user", + "visual-finalization-test-key", + "https://dev.genarrative.world", + ); let _config_guard = crate::tests::write_test_local_config( r#"{"editorApi":{"apiKey":"visual-finalization-test-key"}}"#.to_string(), ); diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs index 8fd82c4b6..ddcc149de 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/action_execution.rs @@ -2184,6 +2184,11 @@ fn static_smoke_failure_receipt_round_trips_owner_diagnostic_from_agent_db() { #[test] fn seed_refresh_downgrades_completed_visual_tasks_when_registered_file_is_missing() { + let _platform_session = crate::platform_session::install_test_platform_session( + "visual-seed-refresh-test-user", + "visual-seed-refresh-test-key", + "https://dev.genarrative.world", + ); let _config_guard = crate::tests::write_test_local_config( r#"{"editorApi":{"apiKey":"visual-seed-refresh-test-key"}}"#.to_string(), ); diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/autonomous_build.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/autonomous_build.rs index 78ce701e8..e23ba5850 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/autonomous_build.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/autonomous_build.rs @@ -467,7 +467,11 @@ fn autonomous_visual_gate_degrades_to_text_without_key_and_requires_images_with_ Some(&GameCreationAppTaskStatus::Completed) ); - write_autonomous_editor_api_config_for_test(&config_dir, "editor-runtime-test-key"); + let _platform_session = crate::platform_session::install_test_platform_session( + "autonomous-visual-gate-test-user", + "autonomous-visual-gate-test-key", + "https://dev.genarrative.world", + ); let with_key_missing_images = autonomous_seed_task_statuses_for_test(&root); assert_eq!( with_key_missing_images.get("art-director"), diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_state.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_state.rs index 8fc86653b..d19454339 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_state.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/runtime_state.rs @@ -3851,6 +3851,11 @@ async fn background_task_recovers_when_assistant_message_cannot_persist() { #[tokio::test] async fn task_update_requires_registered_visual_asset_before_completion() { + let _platform_session = crate::platform_session::install_test_platform_session( + "visual-task-update-test-user", + "visual-task-update-test-key", + "https://dev.genarrative.world", + ); let _config_guard = crate::tests::write_test_local_config( r#"{"editorApi":{"apiKey":"visual-task-update-test-key"}}"#.to_string(), );