mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 01:18:34 +00:00
thumbnail extractor
This commit is contained in:
1 parent
422eabb616
commit
fa7a0c3200
4 files changed
+168
-1
No files matched your search
+39
@@ -11,6 +11,45 @@ pub (crate) fn extract_model_glb(obj: &Map<String, Value>) -> Option<ModelGlbDat
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::webhook_api::hydrate_webhook_contents::hydrate_webhook_contents;
|
||||
use crate::webhook_api::hydrated::hydrated_webhook_contents::HydratedWebhookContents;
|
||||
use crate::webhook_api::raw::raw_webhook_payload::RawWebhookPayload;
|
||||
|
||||
fn load_test_webhook(filename: &str) -> RawWebhookPayload {
|
||||
let path = format!("test_data/webhooks/{}", filename);
|
||||
let json = std::fs::read_to_string(&path)
|
||||
.unwrap_or_else(|e| panic!("Failed to read {}: {}", path, e));
|
||||
serde_json::from_str(&json)
|
||||
.unwrap_or_else(|e| panic!("Failed to parse {}: {}", path, e))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_glb_from_test_file() {
|
||||
let webhook = load_test_webhook("success/model_glb_urls_and_thumbnail_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/0a95eb37/f7UaAhyfcx0BAnYy0GpFM_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(66284788));
|
||||
|
||||
// This payload also has a thumbnail.
|
||||
assert!(contents.thumbnail.is_some());
|
||||
|
||||
// No image/images/video/mesh in this payload.
|
||||
assert!(contents.image.is_none());
|
||||
assert!(contents.images.is_none());
|
||||
assert!(contents.video.is_none());
|
||||
assert!(contents.model_mesh.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn synthetic_model_glb_payload() {
|
||||
|
||||
+37
@@ -11,6 +11,43 @@ pub (crate) fn extract_model_mesh(obj: &Map<String, Value>) -> Option<ModelMeshD
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::webhook_api::hydrate_webhook_contents::hydrate_webhook_contents;
|
||||
use crate::webhook_api::hydrated::hydrated_webhook_contents::HydratedWebhookContents;
|
||||
use crate::webhook_api::raw::raw_webhook_payload::RawWebhookPayload;
|
||||
|
||||
fn load_test_webhook(filename: &str) -> RawWebhookPayload {
|
||||
let path = format!("test_data/webhooks/{}", filename);
|
||||
let json = std::fs::read_to_string(&path)
|
||||
.unwrap_or_else(|e| panic!("Failed to read {}: {}", path, e));
|
||||
serde_json::from_str(&json)
|
||||
.unwrap_or_else(|e| panic!("Failed to parse {}: {}", path, e))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_mesh_from_test_file() {
|
||||
let webhook = load_test_webhook("success/model_mesh_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 mesh = contents.model_mesh.expect("model_mesh should be Some");
|
||||
assert_eq!(mesh.url.as_deref(), Some("https://v3b.fal.media/files/b/0a95eb2d/XCpH7fk-tZVXr1XMUr7DY_mesh-1775972273-765284.glb"));
|
||||
assert_eq!(mesh.content_type.as_deref(), Some("application/octet-stream"));
|
||||
assert_eq!(mesh.file_name.as_deref(), Some("mesh-1775972273-765284.glb"));
|
||||
assert_eq!(mesh.file_size, Some(3886928));
|
||||
|
||||
// No other content types in this payload.
|
||||
assert!(contents.image.is_none());
|
||||
assert!(contents.images.is_none());
|
||||
assert!(contents.video.is_none());
|
||||
assert!(contents.model_glb.is_none());
|
||||
assert!(contents.thumbnail.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn synthetic_model_mesh_payload() {
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
use serde_json::{Map, Value};
|
||||
|
||||
use crate::webhook_api::hydrated::hydrated_webhook_contents::ThumbnailData;
|
||||
|
||||
/// Extract and deserialize the `thumbnail` key from a webhook success payload.
|
||||
pub(crate) fn extract_thumbnail(obj: &Map<String, Value>) -> Option<ThumbnailData> {
|
||||
let value = obj.get("thumbnail")?;
|
||||
serde_json::from_value(value.clone()).ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::webhook_api::hydrate_webhook_contents::hydrate_webhook_contents;
|
||||
use crate::webhook_api::hydrated::hydrated_webhook_contents::HydratedWebhookContents;
|
||||
use crate::webhook_api::raw::raw_webhook_payload::RawWebhookPayload;
|
||||
|
||||
fn load_test_webhook(filename: &str) -> RawWebhookPayload {
|
||||
let path = format!("test_data/webhooks/{}", filename);
|
||||
let json = std::fs::read_to_string(&path)
|
||||
.unwrap_or_else(|e| panic!("Failed to read {}: {}", path, e));
|
||||
serde_json::from_str(&json)
|
||||
.unwrap_or_else(|e| panic!("Failed to parse {}: {}", path, e))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thumbnail_from_model_glb_test_file() {
|
||||
let webhook = load_test_webhook("success/model_glb_urls_and_thumbnail_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 thumbnail = contents.thumbnail.expect("thumbnail should be Some");
|
||||
assert_eq!(thumbnail.url.as_deref(), Some("https://v3b.fal.media/files/b/0a95eb38/yvwGJWZV9TkWZuZvjxZNj_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(93436));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn synthetic_thumbnail_payload() {
|
||||
let obj: serde_json::Map<String, serde_json::Value> = serde_json::from_str(r#"{
|
||||
"thumbnail": {
|
||||
"url": "https://cdn.example.com/thumb.png",
|
||||
"content_type": "image/png",
|
||||
"file_name": "thumb.png",
|
||||
"file_size": 12345
|
||||
}
|
||||
}"#).unwrap();
|
||||
|
||||
let thumb = extract_thumbnail(&obj).expect("should extract thumbnail");
|
||||
assert_eq!(thumb.url.as_deref(), Some("https://cdn.example.com/thumb.png"));
|
||||
assert_eq!(thumb.content_type.as_deref(), Some("image/png"));
|
||||
assert_eq!(thumb.file_name.as_deref(), Some("thumb.png"));
|
||||
assert_eq!(thumb.file_size, Some(12345));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_thumbnail_key_returns_none() {
|
||||
let obj: serde_json::Map<String, serde_json::Value> = serde_json::from_str(r#"{
|
||||
"model_glb": {"url": "https://example.com/model.glb"}
|
||||
}"#).unwrap();
|
||||
|
||||
assert!(extract_thumbnail(&obj).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_mesh_payload_has_no_thumbnail() {
|
||||
let webhook = load_test_webhook("success/model_mesh_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");
|
||||
|
||||
assert!(contents.thumbnail.is_none());
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -3,6 +3,7 @@ pub mod extract_images_payload;
|
||||
pub mod extract_video_payload;
|
||||
pub mod extract_model_glb_payload;
|
||||
pub mod extract_model_mesh_payload;
|
||||
pub mod extract_thumbnail_payload;
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
@@ -23,8 +24,11 @@ pub fn extract_contents_from_payload(payload: &Value) -> Option<ExtractedContent
|
||||
let video = extract_video_payload::extract_video(obj);
|
||||
let model_glb = extract_model_glb_payload::extract_model_glb(obj);
|
||||
let model_mesh = extract_model_mesh_payload::extract_model_mesh(obj);
|
||||
let thumbnail = extract_thumbnail_payload::extract_thumbnail(obj);
|
||||
|
||||
if image.is_none() && images.is_none() && video.is_none() && model_glb.is_none() && model_mesh.is_none() {
|
||||
if image.is_none() && images.is_none() && video.is_none()
|
||||
&& model_glb.is_none() && model_mesh.is_none() && thumbnail.is_none()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -34,5 +38,6 @@ pub fn extract_contents_from_payload(payload: &Value) -> Option<ExtractedContent
|
||||
video,
|
||||
model_glb,
|
||||
model_mesh,
|
||||
thumbnail,
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user