use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64_STANDARD}; use serde_json::json; use shared_contracts::hyper3d as contract; #[test] fn submits_response_contract_keeps_kebab_case_mode() { let payload = serde_json::to_value(contract::Hyper3dTaskSubmitResponse { ok: true, provider: "hyper3d-rodin".to_string(), mode: contract::Hyper3dGenerationMode::ImageToModel, task_uuid: "task-1".to_string(), subscription_key: "sub-1".to_string(), job_uuids: vec!["job-1".to_string()], message: Some("submitted".to_string()), tier: "Gen-2".to_string(), }) .expect("response should serialize"); assert_eq!(payload["mode"], json!("image-to-model")); assert_eq!(payload["subscriptionKey"], json!("sub-1")); } #[tokio::test] async fn image_data_url_limit_error_is_bad_request() { let payload = contract::Hyper3dImageToModelRequest { image_data_urls: vec![ format!( "data:image/png;base64,{}", BASE64_STANDARD.encode(b"\x89PNG\r\n\x1A\nrest") ); 6 ], image_urls: Vec::new(), prompt: None, condition_mode: None, seed: None, geometry_file_format: None, material: None, quality: None, mesh_mode: None, addons: Vec::new(), bbox_condition: None, preview_render: None, }; let error = platform_hyper3d::submit_image_to_model( &platform_hyper3d::Hyper3dSettings { base_url: "https://invalid.local".to_string(), api_key: "test".to_string(), request_timeout_ms: 1, }, payload, ) .await .expect_err("too many images should fail before request"); assert_eq!( error.status_hint(), platform_hyper3d::Hyper3dStatusHint::BadRequest ); }