From f983a0fb9b6326eabf13476dbc5f84f7f6f6322a Mon Sep 17 00:00:00 2001 From: Vika Date: Mon, 23 May 2022 17:39:22 +0300 Subject: templates: add unit test for articles It mostly checks the same old things as with notes, but does check for a name (and as it's explicitly provided, it does work with the buggy version of the `microformats` crate. --- templates/src/lib.rs | 161 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 116 insertions(+), 45 deletions(-) diff --git a/templates/src/lib.rs b/templates/src/lib.rs index f21ffb3..45d1894 100644 --- a/templates/src/lib.rs +++ b/templates/src/lib.rs @@ -8,7 +8,10 @@ pub use login::LoginPage; #[cfg(test)] mod tests { use serde_json::json; - use microformats::types::Document; + use microformats::types::{Document, Item, PropertyValue, Url}; + use std::cell::RefCell; + use std::rc::Rc; + use faker_rand::en_us::internet::Domain; enum PostType { Note, @@ -138,12 +141,69 @@ mod tests { } } + fn check_dt_published( + mf2: &serde_json::Value, + item: &Rc> + ) { + use microformats::types::temporal::Value as TemporalValue; + + let _item = item.borrow(); + let props = _item.properties.borrow(); + assert!(props.contains_key("published")); + + if let Some(PropertyValue::Temporal( + TemporalValue::Timestamp(item) + )) = props.get("published") + .and_then(|v| v.first()) + { + use chrono::{DateTime, FixedOffset, NaiveDateTime}; + + // Faithfully reconstruct the original datetime + // I wonder why not just have an Enum that would + // get you either date, time or a datetime, + // potentially with an offset? + let offset = item.as_offset().unwrap().data; + let ndt: NaiveDateTime = item.as_date().unwrap().data + .and_time(item.as_time().unwrap().data) + // subtract the offset here, since we will add it back + - offset; + let dt = DateTime::::from_utc(ndt, offset); + + let expected: DateTime = chrono::DateTime::parse_from_rfc3339( + mf2["properties"]["published"][0].as_str().unwrap() + ).unwrap(); + + assert_eq!(dt, expected); + } else { + unreachable!() + } + } + + fn check_e_content( + mf2: &serde_json::Value, + item: &Rc> + ) { + let _item = item.borrow(); + let props = _item.properties.borrow(); + assert!(props.contains_key("content")); + + if let Some(PropertyValue::Fragment(content)) = + props.get("content") + .and_then(|v| v.first()) + { + assert_eq!( + content.html, + mf2["properties"]["content"][0]["html"].as_str().unwrap() + ); + } else { + unreachable!() + } + + } + #[test] #[ignore = "see https://gitlab.com/maxburon/microformats-parser/-/issues/7"] fn test_note() { - use microformats::types::PropertyValue; - use faker_rand::en_us::internet::Domain; - test_logger::ensure_env_logger_initialized(); let mf2 = gen_random_post( @@ -154,53 +214,19 @@ mod tests { let html = crate::templates::Entry { post: &mf2 }.to_string(); - println!("\n```html\n{}\n```", &html); - let url: microformats::types::Url = mf2["properties"]["uid"][0].as_str() - .unwrap() - .parse() + + let url: Url = mf2.pointer("/properties/uid/0") + .and_then(|i| i.as_str()) + .and_then(|u| u.parse().ok()) .unwrap(); let parsed: Document = microformats::from_html(&html, url.clone()).unwrap(); - let item = parsed.get_item_by_url(&url).unwrap(); - println!("\n```json\n{}\n```", serde_json::to_string_pretty(&item).unwrap()); - if let PropertyValue::Item(item) = item { + if let Some(PropertyValue::Item(item)) = parsed.get_item_by_url(&url) { let _item = item.borrow(); let props = _item.properties.borrow(); - if let PropertyValue::Fragment(content) = props.get("content").and_then(|v| v.first()).unwrap() { - assert_eq!(content.html, mf2["properties"]["content"][0]["html"].as_str().unwrap()); - } else { - unreachable!() - } - - assert!(props.contains_key("published")); - use microformats::types::temporal::Value as TemporalValue; - if let Some(PropertyValue::Temporal( - TemporalValue::Timestamp(item) - )) = props.get("published") - .and_then(|v| v.first()) - { - use chrono::{DateTime, FixedOffset, NaiveDateTime}; - - // Faithfully reconstruct the original datetime - // I wonder why not just have an Enum that would - // get you either date, time or a datetime, - // potentially with an offset? - let offset = item.as_offset().unwrap().data; - let ndt: NaiveDateTime = item.as_date().unwrap().data - .and_time(item.as_time().unwrap().data) - - offset; - let dt = DateTime::::from_utc(ndt, offset); - - let expected: DateTime = chrono::DateTime::parse_from_rfc3339( - mf2["properties"]["published"][0].as_str().unwrap() - ).unwrap(); - - assert_eq!(dt, expected); - } else { - panic!("Failed to find datetime in properties!"); - } - + check_e_content(&mf2, &item); + check_dt_published(&mf2, &item); assert!(props.contains_key("uid")); assert!(props.contains_key("url")); assert!(props.get("url") @@ -214,4 +240,49 @@ mod tests { unreachable!() } } + + #[test] + fn test_article() { + test_logger::ensure_env_logger_initialized(); + + let mf2 = gen_random_post( + &rand::random::().to_string(), + PostType::Article + ); + let html = crate::templates::Entry { + post: &mf2 + }.to_string(); + let url: Url = mf2.pointer("/properties/uid/0") + .and_then(|i| i.as_str()) + .and_then(|u| u.parse().ok()) + .unwrap(); + let parsed: Document = microformats::from_html(&html, url.clone()).unwrap(); + + if let Some(PropertyValue::Item(item)) = parsed.get_item_by_url(&url) { + let _item = item.borrow(); + let props = _item.properties.borrow(); + + check_e_content(&mf2, &item); + check_dt_published(&mf2, &item); + assert!(props.contains_key("uid")); + assert!(props.contains_key("url")); + assert!(props.get("url") + .unwrap() + .iter() + .any(|i| i == props.get("uid").and_then(|v| v.first()).unwrap())); + assert!(props.contains_key("name")); + if let Some(PropertyValue::Plain(name)) = props.get("name").and_then(|v| v.first()) { + assert_eq!( + name, + mf2.pointer("/properties/name/0") + .and_then(|v| v.as_str()) + .unwrap() + ); + } else { + panic!("Name wasn't a plain property!"); + } + } else { + unreachable!() + } + } } -- cgit 1.4.1