diff options
Diffstat (limited to 'templates/src/lib.rs')
-rw-r--r-- | templates/src/lib.rs | 347 |
1 files changed, 0 insertions, 347 deletions
diff --git a/templates/src/lib.rs b/templates/src/lib.rs deleted file mode 100644 index 39f1075..0000000 --- a/templates/src/lib.rs +++ /dev/null @@ -1,347 +0,0 @@ -mod templates; -pub use templates::{ErrorPage, MainPage, Template, POSTS_PER_PAGE, Entry, VCard, Feed}; -mod onboarding; -pub use onboarding::OnboardingPage; -mod login; -pub use login::LoginPage; - -#[cfg(test)] -mod tests { - use faker_rand::lorem::Word; - use serde_json::json; - 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, - Article, - ReplyTo(serde_json::Value), - ReplyToLink(String), - LikeOf(serde_json::Value), - LikeOfLink(String) - } - - fn gen_hcard(domain: &str) -> serde_json::Value { - use faker_rand::en_us::names::FirstName; - - json!({ - "type": ["h-card"], - "properties": { - "name": [rand::random::<FirstName>().to_string()], - "photo": [format!("https://{domain}/media/me.png")], - "uid": [format!("https://{domain}/")], - "url": [format!("https://{domain}/")] - } - }) - } - - fn gen_random_post(domain: &str, kind: PostType) -> serde_json::Value { - use faker_rand::lorem::{Paragraph, Sentence}; - - fn html(content: Paragraph) -> serde_json::Value { - json!({ - "html": format!("<p>{}</p>", content), - "value": content.to_string() - }) - } - - let uid = format!( - "https://{domain}/posts/{}-{}-{}", - rand::random::<Word>(), rand::random::<Word>(), rand::random::<Word>() - ); - let dt = chrono::offset::Local::now() - .to_rfc3339_opts(chrono::SecondsFormat::Secs, true); - - match kind { - PostType::Note => { - let content = rand::random::<Paragraph>(); - - json!({ - "type": ["h-entry"], - "properties": { - "content": [html(content)], - "published": [dt], - "uid": [&uid], "url": [&uid], - "author": [gen_hcard(domain)] - } - }) - } - PostType::Article => { - let content = rand::random::<Paragraph>(); - let name = rand::random::<Sentence>(); - - json!({ - "type": ["h-entry"], - "properties": { - "content": [html(content)], - "published": [dt], - "uid": [&uid], "url": [&uid], - "author": [gen_hcard(domain)], - "name": [name.to_string()] - } - }) - } - PostType::ReplyTo(ctx) => { - let content = rand::random::<Paragraph>(); - - json!({ - "type": ["h-entry"], - "properties": { - "content": [html(content)], - "published": [dt], - "uid": [&uid], "url": [&uid], - "author": [gen_hcard(domain)], - "in-reply-to": [{ - "type": ["h-cite"], - "properties": ctx["properties"] - }] - } - }) - }, - PostType::ReplyToLink(link) => { - let content = rand::random::<Paragraph>(); - - json!({ - "type": ["h-entry"], - "properties": { - "content": [html(content)], - "published": [dt], - "uid": [&uid], "url": [&uid], - "author": [gen_hcard(domain)], - "in-reply-to": [link] - } - }) - }, - PostType::LikeOf(ctx) => { - json!({ - "type": ["h-entry"], - "properties": { - "published": [dt], - "author": [gen_hcard(domain)], - "uid": [&uid], "url": [&uid], - "like-of": [{ - "type": ["h-cite"], - "properties": ctx["properties"] - }] - } - }) - }, - PostType::LikeOfLink(link) => { - json!({ - "type": ["h-entry"], - "properties": { - "published": [dt], - "author": [gen_hcard(domain)], - "uid": [&uid], "url": [&uid], - "like-of": [link] - } - }) - } - } - } - - 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() { - test_logger::ensure_env_logger_initialized(); - - let mf2 = gen_random_post( - &rand::random::<Domain>().to_string(), - PostType::Note - ); - - 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())); - // XXX: fails because of https://gitlab.com/maxburon/microformats-parser/-/issues/7 - assert!(!props.contains_key("name")); - - } else { - 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!() - } - } - - #[test] - fn test_like_of() { - test_logger::ensure_env_logger_initialized(); - - for likeof in [ - PostType::LikeOf(gen_random_post( - &rand::random::<Domain>().to_string(), - PostType::Note - )), - PostType::LikeOfLink(format!( - "https://{}/posts/{}-{}-{}", - &rand::random::<Domain>(), - &rand::random::<Word>(), - &rand::random::<Word>(), - &rand::random::<Word>(), - )) - ] { - let mf2 = gen_random_post( - &rand::random::<Domain>().to_string(), - likeof - ); - let url: Url = mf2.pointer("/properties/uid/0") - .and_then(|i| i.as_str()) - .and_then(|u| u.parse().ok()) - .unwrap(); - let html = crate::templates::Entry { - post: &mf2 - }.to_string(); - let parsed: Document = microformats::from_html(&html, url.clone()).unwrap(); - - if let Some(item) = parsed.items.get(0) { - let _item = item.borrow(); - let props = _item.properties.borrow(); - - check_dt_published(&mf2, item); - assert!(props.contains_key("like-of")); - match props.get("like-of").and_then(|v| v.first()) { - Some(PropertyValue::Url(url)) => { - assert_eq!( - url, - &mf2.pointer("/properties/like-of/0") - .and_then(|i| i.as_str()) - .or_else(|| mf2.pointer("/properties/like-of/0/properties/uid/0").and_then(|i| i.as_str())) - .and_then(|u| u.parse::<Url>().ok()) - .unwrap() - ); - } - Some(PropertyValue::Item(_cite)) => { - todo!() - } - other => panic!("Unexpected value in like-of: {:?}", other) - } - } else { - unreachable!() - } - } - } -} |