about summary refs log tree commit diff
path: root/templates
diff options
context:
space:
mode:
Diffstat (limited to 'templates')
-rw-r--r--templates/src/lib.rs161
1 files 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<RefCell<Item>>
+    ) {
+        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::<FixedOffset>::from_utc(ndt, offset);
+
+            let expected: DateTime<FixedOffset> = 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<RefCell<Item>>
+    ) {
+        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::<FixedOffset>::from_utc(ndt, offset);
-
-                let expected: DateTime<FixedOffset> = 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::<Domain>().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!()
+        }
+    }
 }