diff --git a/src/daemon/query.rs b/src/daemon/query.rs index f491287..fa2124c 100644 --- a/src/daemon/query.rs +++ b/src/daemon/query.rs @@ -2030,4 +2030,214 @@ mod sns_tests { assert_eq!(escape_like_pattern("中文关键词"), "中文关键词"); assert_eq!(escape_like_pattern(""), ""); } + + fn media_object(value: &Value) -> &serde_json::Map { + value.as_object().expect("media entry should be an object") + } + + #[test] + fn single_image_media() { + let xml = r#" + + + + + + 2 + https://szmmsns.qpic.cn/<redacted>/image.jpg + https://szmmsns.qpic.cn/<redacted>/thumb.jpg + + + + + + + "#; + + let media = parse_post_media(xml); + assert_eq!(media.len(), 1); + + let item = media_object(&media[0]); + assert_eq!(item.get("type").and_then(Value::as_str), Some("2")); + assert_eq!( + item.get("url").and_then(Value::as_str), + Some("https://szmmsns.qpic.cn//image.jpg") + ); + assert_eq!( + item.get("thumb").and_then(Value::as_str), + Some("https://szmmsns.qpic.cn//thumb.jpg") + ); + assert_eq!(item.get("url_enc_idx").and_then(Value::as_str), Some("1")); + assert_eq!( + item.get("url_key").and_then(Value::as_str), + Some("placeholder-key") + ); + assert_eq!( + item.get("url_token").and_then(Value::as_str), + Some("placeholder-token") + ); + assert_eq!( + item.get("md5").and_then(Value::as_str), + Some("placeholder-md5") + ); + assert_eq!(item.get("width").and_then(Value::as_i64), Some(1440)); + assert_eq!(item.get("height").and_then(Value::as_i64), Some(1080)); + assert_eq!(item.get("total_size").and_then(Value::as_i64), Some(123456)); + } + + #[test] + fn three_images_media() { + let xml = r#" + + + + + + 2 + 10 + https://szmmsns.qpic.cn/<redacted>/image-1.jpg + https://szmmsns.qpic.cn/<redacted>/thumb-1.jpg + + + + 2 + 11 + https://szmmsns.qpic.cn/<redacted>/image-2.jpg + https://szmmsns.qpic.cn/<redacted>/thumb-2.jpg + + + + 6 + https://szmmsns.qpic.cn/<redacted>/image-3.jpg + https://szmmsns.qpic.cn/<redacted>/thumb-3.jpg + + + + + + + "#; + + let media = parse_post_media(xml); + assert_eq!(media.len(), 3); + + let first = media_object(&media[0]); + assert_eq!(first.get("sub_type").and_then(Value::as_str), Some("10")); + assert_eq!( + first.get("url_key").and_then(Value::as_str), + Some("placeholder-key-1") + ); + + let second = media_object(&media[1]); + assert_eq!(second.get("sub_type").and_then(Value::as_str), Some("11")); + assert_eq!(second.get("width").and_then(Value::as_i64), Some(300)); + + let third = media_object(&media[2]); + assert_eq!(third.get("type").and_then(Value::as_str), Some("6")); + assert_eq!( + third.get("thumb_key").and_then(Value::as_str), + Some("placeholder-thumb-key-3") + ); + } + + #[test] + fn video_media() { + let xml = r#" + + + + + + 15 + https://szmmsns.qpic.cn/<redacted>/video.mp4 + https://szmmsns.qpic.cn/<redacted>/video-thumb.jpg + + <placeholder-video-md5> + 37 + + + + + + "#; + + let media = parse_post_media(xml); + assert_eq!(media.len(), 1); + + let item = media_object(&media[0]); + assert_eq!( + item.get("video_md5").and_then(Value::as_str), + Some("") + ); + assert_eq!(item.get("video_duration").and_then(Value::as_i64), Some(37)); + assert!(!item.contains_key("total_size")); + } + + #[test] + fn text_only_post() { + let without_media_list = r#" + + + + 1 + + + + "#; + let empty_media_list = r#" + + + + + + + + "#; + + assert!(parse_post_media(without_media_list).is_empty()); + assert!(parse_post_media(empty_media_list).is_empty()); + } + + #[test] + fn malformed_xml() { + let xml = r#" + + + + + + 2 + + + + + "#; + + assert!(parse_post_media(xml).is_empty()); + } + + #[test] + fn size_without_total_size_omits_total_size_key() { + let xml = r#" + + + + + + 2 + + + + + + + "#; + + let media = parse_post_media(xml); + assert_eq!(media.len(), 1); + let item = media_object(&media[0]); + assert_eq!(item.get("width").and_then(Value::as_i64), Some(640)); + assert_eq!(item.get("height").and_then(Value::as_i64), Some(480)); + assert!(!item.contains_key("total_size")); + } }