extra tests

This commit is contained in:
Brandon Thomas
2026-07-10 15:48:28 -04:00
parent cebe1b5f4b
commit 3fe04d0bf3
3 changed files with 115 additions and 3 deletions
@@ -125,15 +125,19 @@ pub struct ModelMeshData {
pub url: Option<String>,
}
/// Data under `payload.model_urls` (e.g. Hunyuan 3D 3.0): a map of the
/// generation's output files by format. Any slot may be null. The `glb`
/// entry frequently duplicates `payload.model_glb` (same URL), but may
/// Data under `payload.model_urls` (e.g. Hunyuan 3D 3.0 / 3.1): a map of the
/// generation's output files by format. Any slot may be null or absent. The
/// `glb` entry frequently duplicates `payload.model_glb` (same URL), but may
/// point to a different file.
#[derive(Debug, Deserialize)]
pub struct ModelUrlsData {
pub fbx: Option<ModelGlbData>,
pub glb: Option<ModelGlbData>,
/// OBJ material file (Hunyuan 3D 3.1).
pub mtl: Option<ModelGlbData>,
pub obj: Option<ModelGlbData>,
/// PBR texture image for the OBJ (Hunyuan 3D 3.1).
pub texture: Option<ModelGlbData>,
pub usdz: Option<ModelGlbData>,
}
@@ -55,6 +55,8 @@ mod tests {
assert_eq!(urls_obj.file_size, Some(41107268));
assert!(model_urls.fbx.is_none());
assert!(model_urls.mtl.is_none());
assert!(model_urls.texture.is_none());
assert!(model_urls.usdz.is_none());
let thumbnail = contents.thumbnail.expect("thumbnail should be Some");
@@ -68,6 +70,63 @@ mod tests {
assert!(contents.preprocessed_image.is_none());
}
#[test]
fn model_urls_and_thumbnail_from_hunyuan_3d_3p1_test_file() {
let webhook = load_test_webhook("success/hunyuan_3d_3p1_model_urls_thumbnail_payload_1.json");
let result = hydrate_webhook_contents(&webhook);
let HydratedWebhookContents::Success(data) = result else {
panic!("Expected Success, got {:?}", result);
};
let contents = data.extracted_contents
.expect("extracted_contents should be Some");
let glb = contents.model_glb.expect("model_glb should be Some");
assert_eq!(glb.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1ba44/OdgIv8M9EkaBP_Mh4TVAB_model.glb"));
assert_eq!(glb.content_type.as_deref(), Some("model/gltf-binary"));
assert_eq!(glb.file_name.as_deref(), Some("model.glb"));
assert_eq!(glb.file_size, Some(64261364));
let model_urls = contents.model_urls.expect("model_urls should be Some");
// The `glb` slot duplicates `model_glb` in this payload (same URL).
let urls_glb = model_urls.glb.expect("model_urls.glb should be Some");
assert_eq!(urls_glb.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1ba44/OdgIv8M9EkaBP_Mh4TVAB_model.glb"));
let urls_obj = model_urls.obj.expect("model_urls.obj should be Some");
assert_eq!(urls_obj.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1ba43/WxPMNbzsDxaGRCmGNgNAL_c3a871e997ecd5f889bf671630de23b4.obj"));
assert_eq!(urls_obj.content_type.as_deref(), Some("model/obj"));
assert_eq!(urls_obj.file_size, Some(34563830));
// 3.1 additionally ships the OBJ's material and PBR texture files.
let urls_mtl = model_urls.mtl.expect("model_urls.mtl should be Some");
assert_eq!(urls_mtl.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1ba42/1T5VCp_xD0zCJlTLE96iK_material.mtl"));
assert_eq!(urls_mtl.content_type.as_deref(), Some("text/plain"));
assert_eq!(urls_mtl.file_name.as_deref(), Some("material.mtl"));
assert_eq!(urls_mtl.file_size, Some(245));
let urls_texture = model_urls.texture.expect("model_urls.texture should be Some");
assert_eq!(urls_texture.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1ba43/aKp3mMB9nrhlKfV2KVf0S_texture_pbr_20250901.png"));
assert_eq!(urls_texture.content_type.as_deref(), Some("image/png"));
assert_eq!(urls_texture.file_name.as_deref(), Some("texture_pbr_20250901.png"));
assert_eq!(urls_texture.file_size, Some(22794575));
assert!(model_urls.fbx.is_none());
assert!(model_urls.usdz.is_none());
// The thumbnail is attached to the GLB as its cover image downstream.
let thumbnail = contents.thumbnail.expect("thumbnail should be Some");
assert_eq!(thumbnail.url.as_deref(), Some("https://v3b.fal.media/files/b/0aa1ba44/njq8zYhYahJNNQkGGiEZW_preview.png"));
assert_eq!(thumbnail.content_type.as_deref(), Some("image/png"));
assert_eq!(thumbnail.file_name.as_deref(), Some("preview.png"));
assert_eq!(thumbnail.file_size, Some(141254));
assert!(contents.model_glb_pbr.is_none());
assert!(contents.model_mesh.is_none());
assert!(contents.preprocessed_image.is_none());
}
#[test]
fn synthetic_model_urls_payload_with_distinct_glb() {
let obj: serde_json::Map<String, serde_json::Value> = serde_json::from_str(r#"{
@@ -0,0 +1,49 @@
{
"error": null,
"gateway_request_id": "019f4d79-35fd-7462-85be-359c8232f56e",
"payload": {
"model_glb": {
"content_type": "model/gltf-binary",
"file_name": "model.glb",
"file_size": 64261364,
"url": "https://v3b.fal.media/files/b/0aa1ba44/OdgIv8M9EkaBP_Mh4TVAB_model.glb"
},
"model_urls": {
"fbx": null,
"glb": {
"content_type": "model/gltf-binary",
"file_name": "model.glb",
"file_size": 64261364,
"url": "https://v3b.fal.media/files/b/0aa1ba44/OdgIv8M9EkaBP_Mh4TVAB_model.glb"
},
"mtl": {
"content_type": "text/plain",
"file_name": "material.mtl",
"file_size": 245,
"url": "https://v3b.fal.media/files/b/0aa1ba42/1T5VCp_xD0zCJlTLE96iK_material.mtl"
},
"obj": {
"content_type": "model/obj",
"file_name": "c3a871e997ecd5f889bf671630de23b4.obj",
"file_size": 34563830,
"url": "https://v3b.fal.media/files/b/0aa1ba43/WxPMNbzsDxaGRCmGNgNAL_c3a871e997ecd5f889bf671630de23b4.obj"
},
"texture": {
"content_type": "image/png",
"file_name": "texture_pbr_20250901.png",
"file_size": 22794575,
"url": "https://v3b.fal.media/files/b/0aa1ba43/aKp3mMB9nrhlKfV2KVf0S_texture_pbr_20250901.png"
},
"usdz": null
},
"seed": null,
"thumbnail": {
"content_type": "image/png",
"file_name": "preview.png",
"file_size": 141254,
"url": "https://v3b.fal.media/files/b/0aa1ba44/njq8zYhYahJNNQkGGiEZW_preview.png"
}
},
"request_id": "019f4d79-35fd-7462-85be-359c8232f56e",
"status": "OK"
}