use chrono::{DateTime, Utc};
use rss2email_lib::{
xml::{error::ParserError, parse_web_feed},
Blog, Post,
};
use pretty_assertions::assert_eq;
fn read_file(dir_name: &str, file_name: &str) -> String {
use std::fs;
use std::path::PathBuf;
let mut file_path = PathBuf::from("test-data");
file_path.push(dir_name);
file_path.push(file_name);
fs::read_to_string(file_path).expect("Cannot read feed ")
}
fn read_rss(file_name: &str) -> String {
read_file("rss-feeds", file_name)
}
fn read_atom(file_name: &str) -> String {
read_file("atom-feeds", file_name)
}
fn post_date(value: &str) -> DateTime<Utc> {
value
.parse::<DateTime<Utc>>()
.unwrap_or_else(|_| panic!("Invalid date {value}"))
}
#[test]
fn test_parse_brief_single_entry_atom() {
let content = read_atom("brief-single-entry.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "Example Feed".into(),
most_recent_pub_date: post_date("2003-12-13T18:30:02+00:00"),
posts: vec![Post {
title: "Atom-Powered Robots Run Amok".into(),
link: "http://example.org/2003/12/13/atom03".into(),
description: Some("Some text.".into()),
pub_date: post_date("2003-12-13T18:30:02+00:00"),
}],
}
);
}
#[test]
fn test_parse_complex_single_entry_atom() {
let content = read_atom("complex-single-entry.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "dive into mark".into(),
most_recent_pub_date: post_date("2003-12-13T08:29:29-04:00"),
posts: vec![Post {
title: "Atom draft-07 snapshot".into(),
link: "http://example.org/2005/04/02/atom".into(),
description: None,
pub_date: post_date("2003-12-13T08:29:29-04:00"),
}],
}
);
}
#[test]
fn test_parse_atom_without_entry() {
let content = read_atom("no-entries.xml");
let result = parse_web_feed(&content);
assert!(result.is_err());
let is_empty_feed_error = match result.expect_err("Should error") {
ParserError::Parse(p) => p.contains("Empty feed"),
ParserError::Date(_) => false,
};
assert!(is_empty_feed_error);
}
#[test]
fn test_parse_atom_with_many_entries() {
let content = read_atom("multi-entries.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
let first_date = post_date("2022-09-18T21:00:00+00:00");
let second_date = post_date("2022-10-21T21:10:00+00:00");
assert_eq!(
blog,
Blog {
title: "Multi-Entries Feed".into(),
most_recent_pub_date: second_date,
posts: vec![
Post {
title: "First title".into(),
link: "http://awesome.com/link1.html".into(),
description: Some("First content".into()),
pub_date: first_date,
},
Post {
title: "Second title".into(),
link: "http://com.net/why-not.html".into(),
description: None,
pub_date: second_date,
}
],
}
);
}
#[test]
fn test_parse_atom_text_with_html_tags() {
let content = read_atom("entry-with-html.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
let date = post_date("2022-09-18T21:00:00+00:00");
assert_eq!(
blog,
Blog {
title: "Multi-Entries Feed".into(),
most_recent_pub_date: date,
posts: vec![Post {
title: "<b>Star</b> City".into(),
link: "http://link.com".into(),
description: Some(
"How did it work? <i>Details</i> <a href=\"http://liftoff.msfc.nasa.gov\">here</a>"
.into()
),
pub_date: date,
}],
}
);
}
#[test]
fn test_parse_rss_data() {
let content = read_rss("self-rss.xml");
let _blog = parse_web_feed(&content).expect("Parsed content");
}
#[test]
fn test_parse_rss_0_91() {
let content = read_rss("sample-0_91.xml");
let result = parse_web_feed(&content);
assert!(result.is_err());
}
#[test]
fn test_parse_rss_0_92() {
let content = read_rss("sample-0_92.xml");
let result = parse_web_feed(&content);
assert!(result.is_err());
}
#[test]
fn test_parse_rss_2() {
let content = read_rss("sample-2.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "Liftoff News".into(),
most_recent_pub_date: post_date("2003-06-10T04:00:00+00:00"),
posts: vec![Post {
title: "Star City".into(),
link:"http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp".into(),
description: Some("How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's <a href=\"http://howe.iki.rssi.ru/GCTC/gc...".into()),
pub_date: post_date("2003-06-03T09:39:21+00:00"),
},
Post {
title: "The Engine That Does More".into(),
link:"http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp".into(),
description: Some("Before man travels to Mars, NASA hopes to design new engines that will let us fly through the Solar System more quickly. The proposed VASIMR engine would do that.".into()),
pub_date: post_date("2003-05-27T08:37:32+00:00"),
},
Post {
title: "Astronauts' Dirty Laundry".into(),
link:"http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp".into(),
description: Some("Compared to earlier spacecraft, the International Space Station has many luxuries, but laundry facilities are not one of them. Instead, astronauts have other options.".into()),
pub_date: post_date("2003-05-20T08:56:02+00:00"),
}],
});
}
#[test]
fn test_parse_rss_text_with_html_tags() {
let content = read_rss("v2-with-html.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "Liftoff News".into(),
most_recent_pub_date: post_date("2003-06-10T04:00:00+00:00"),
posts: vec![Post {
title: "<b>Star</b> City".into(),
link: "http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp".into(),
description: Some(
"How did it work? <i>Details</i> <a href=\"http://liftoff.msfc.nasa.gov\">here</a>"
.into()
),
pub_date: post_date("2003-06-03T09:39:21+00:00"),
}],
}
);
}
#[test]
fn test_parse_rss_without_items() {
let content = read_rss("v2-without-items.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "NoNews".into(),
most_recent_pub_date: post_date("2003-06-10T04:00:00+00:00"),
posts: vec![]
}
);
}
#[test]
fn test_parse_rss_entry_without_link() {
let content = read_rss("v2-without-link.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "Liftoff News".into(),
most_recent_pub_date: post_date("2003-06-10T04:00:00+00:00"),
posts: vec![
Post {
title: "Star City".into(),
link: "http://abc.com".into(),
description: None,
pub_date: post_date("2003-06-03T09:39:21+00:00"),
},
Post {
title: "Planet City".into(),
link: "http://def.com".into(),
description: Some("def".into()),
pub_date: post_date("2003-06-03T09:39:21+00:00"),
}
],
}
);
}
#[test]
fn test_parse_rss_entry_without_title_and_short_description() {
let content = read_rss("v2-without-title-short-desc.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "Liftoff News".into(),
most_recent_pub_date: post_date("2003-06-10T04:00:00+00:00"),
posts: vec![Post {
title: "Liftoff at Star City".into(),
link: "http://liftoff.msfc.nasa.gov".into(),
description: None,
pub_date: post_date("2003-06-03T09:39:21+00:00"),
}],
}
);
}
#[test]
fn test_parse_rss_entry_without_title_and_long_description() {
let content = read_rss("v2-without-title-long-desc.xml");
let blog = parse_web_feed(&content).expect("Parsed content");
assert_eq!(
blog,
Blog {
title: "Liftoff News".into(),
most_recent_pub_date: post_date("2003-06-10T04:00:00+00:00"),
posts: vec![Post {
title: "How do Americans get ready to work with Russians a...".into(),
link: "http://liftoff.msfc.nasa.gov".into(),
description: Some(
"How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's Star City."
.into()
),
pub_date: post_date("2003-06-03T09:39:21+00:00"),
}],
}
);
}