use crate::{
manager::PostArchiverManager,
query::{author::AuthorSort, Countable, Paginate, Query, SortDir, Sortable},
tests::helpers,
Author, Post,
};
use chrono::Utc;
#[test]
fn test_get_author_exists() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let id = helpers::add_author(&m, "Alice".into(), Some(now));
let author = m.get_author(id).unwrap().unwrap();
assert_eq!(author.id, id);
assert_eq!(author.name, "Alice");
}
#[test]
fn test_get_author_not_found() {
let m = PostArchiverManager::open_in_memory().unwrap();
use crate::AuthorId;
let result = m.get_author(AuthorId::from(9999u32)).unwrap();
assert!(result.is_none());
}
#[test]
fn test_find_author_by_alias_found() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let plt = helpers::add_platform(&m, "github".into());
let id = helpers::add_author(&m, "Octocat".into(), Some(now));
helpers::add_author_aliases(&m, id, vec![("octocat".into(), plt, None)]);
let found = m.find_author_by_alias("octocat", plt).unwrap();
assert_eq!(found, Some(id));
}
#[test]
fn test_find_author_by_alias_not_found() {
let m = PostArchiverManager::open_in_memory().unwrap();
let plt = helpers::add_platform(&m, "x".into());
let result = m.find_author_by_alias("nobody", plt).unwrap();
assert!(result.is_none());
}
#[test]
fn test_find_author_by_alias_wrong_platform() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let plt_a = helpers::add_platform(&m, "platformA".into());
let plt_b = helpers::add_platform(&m, "platformB".into());
let id = helpers::add_author(&m, "Alice".into(), Some(now));
helpers::add_author_aliases(&m, id, vec![("alice".into(), plt_a, None)]);
let result = m.find_author_by_alias("alice", plt_b).unwrap();
assert!(result.is_none());
}
#[test]
fn test_authors_empty() {
let m = PostArchiverManager::open_in_memory().unwrap();
let authors = m.authors().query::<Author>().unwrap();
assert!(authors.is_empty());
}
#[test]
fn test_authors_returns_all() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let id1 = helpers::add_author(&m, "Alice".into(), Some(now));
let id2 = helpers::add_author(&m, "Bob".into(), Some(now));
let authors = m.authors().query::<Author>().unwrap();
assert_eq!(authors.len(), 2);
let ids: Vec<_> = authors.iter().map(|a| a.id).collect();
assert!(ids.contains(&id1));
assert!(ids.contains(&id2));
}
#[test]
fn test_authors_name_contains() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
helpers::add_author(&m, "Alice Smith".into(), Some(now));
helpers::add_author(&m, "Bob Jones".into(), Some(now));
helpers::add_author(&m, "Alice Wonderland".into(), Some(now));
let mut q = m.authors();
q.name.contains("Alice");
let results = q.query::<Author>().unwrap();
assert_eq!(results.len(), 2);
assert!(results.iter().all(|a| a.name.contains("Alice")));
}
#[test]
fn test_authors_name_contains_case_insensitive() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
helpers::add_author(&m, "alice".into(), Some(now));
helpers::add_author(&m, "ALICE".into(), Some(now));
let mut q = m.authors();
q.name.contains("alice");
let results = q.query::<Author>().unwrap();
assert_eq!(results.len(), 2);
}
#[test]
fn test_authors_name_contains_no_match() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
helpers::add_author(&m, "Alice".into(), Some(now));
let mut q = m.authors();
q.name.contains("xyz");
let results = q.query::<Author>().unwrap();
assert!(results.is_empty());
}
#[test]
fn test_authors_sort_by_name_asc() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
helpers::add_author(&m, "Zara".into(), Some(now));
helpers::add_author(&m, "Anna".into(), Some(now));
helpers::add_author(&m, "Mike".into(), Some(now));
let authors = m
.authors()
.sort(AuthorSort::Name, SortDir::Asc)
.query::<Author>()
.unwrap();
let names: Vec<_> = authors.iter().map(|a| a.name.as_str()).collect();
assert_eq!(names, vec!["Anna", "Mike", "Zara"]);
}
#[test]
fn test_authors_sort_by_name_desc() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
helpers::add_author(&m, "Zara".into(), Some(now));
helpers::add_author(&m, "Anna".into(), Some(now));
helpers::add_author(&m, "Mike".into(), Some(now));
let authors = m
.authors()
.sort(AuthorSort::Name, SortDir::Desc)
.query::<Author>()
.unwrap();
let names: Vec<_> = authors.iter().map(|a| a.name.as_str()).collect();
assert_eq!(names, vec!["Zara", "Mike", "Anna"]);
}
#[test]
fn test_authors_pagination() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
for i in 0..5u32 {
helpers::add_author(&m, format!("Author-{i:02}"), Some(now));
}
let page1 = m
.authors()
.sort(AuthorSort::Name, SortDir::Asc)
.pagination(2, 0)
.query::<Author>()
.unwrap();
let page2 = m
.authors()
.sort(AuthorSort::Name, SortDir::Asc)
.pagination(2, 1)
.query::<Author>()
.unwrap();
assert_eq!(page1.len(), 2);
assert_eq!(page2.len(), 2);
let ids1: Vec<_> = page1.iter().map(|a| a.id).collect();
let ids2: Vec<_> = page2.iter().map(|a| a.id).collect();
assert!(ids1.iter().all(|id| !ids2.contains(id)));
}
#[test]
fn test_authors_with_total() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
for i in 0..6u32 {
helpers::add_author(&m, format!("A{i}"), Some(now));
}
let result = m
.authors()
.pagination(2, 0)
.with_total()
.query::<Author>()
.unwrap();
assert_eq!(result.total, 6);
assert_eq!(result.items.len(), 2);
}
#[test]
fn test_authors_with_total_filtered() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
helpers::add_author(&m, "Alice A".into(), Some(now));
helpers::add_author(&m, "Alice B".into(), Some(now));
helpers::add_author(&m, "Bob C".into(), Some(now));
let mut q = m.authors();
q.name.contains("Alice");
let result = q.with_total().query::<Author>().unwrap();
assert_eq!(result.total, 2);
assert_eq!(result.items.len(), 2);
}
#[test]
fn test_authors_with_relations() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let plt = helpers::add_platform(&m, "gh".into());
let author_id = helpers::add_author(&m, "Dev".into(), Some(now));
helpers::add_author_aliases(&m, author_id, vec![("dev".into(), plt, None)]);
let post_id = helpers::add_post(&m, "Post".into(), None, None, Some(now), Some(now));
helpers::add_post_authors(&m, post_id, &[author_id]);
let authors = m.authors().query::<Author>().unwrap();
assert_eq!(authors.len(), 1);
assert_eq!(authors[0].id, author_id);
let aliases = m.bind(author_id).list_aliases().unwrap();
assert_eq!(aliases.len(), 1);
let posts = m.bind(author_id).list_posts().unwrap();
assert_eq!(posts.len(), 1);
assert_eq!(posts[0], post_id);
}
#[test]
fn test_authors_relations_with_total() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
for i in 0..4u32 {
helpers::add_author(&m, format!("A{i}"), Some(now));
}
let result = m
.authors()
.pagination(2, 0)
.with_total()
.query::<Author>()
.unwrap();
assert_eq!(result.total, 4);
assert_eq!(result.items.len(), 2);
}
#[test]
fn test_author_aliases_via_bind() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let plt1 = helpers::add_platform(&m, "github".into());
let plt2 = helpers::add_platform(&m, "twitter".into());
let id = helpers::add_author(&m, "Dev".into(), Some(now));
helpers::add_author_aliases(
&m,
id,
vec![
("dev-gh".into(), plt1, None),
(
"dev-tw".into(),
plt2,
Some("https://twitter.com/dev".into()),
),
],
);
let aliases = m.bind(id).list_aliases().unwrap();
assert_eq!(aliases.len(), 2);
let sources: Vec<_> = aliases.iter().map(|a| a.source.as_str()).collect();
assert!(sources.contains(&"dev-gh"));
assert!(sources.contains(&"dev-tw"));
}
#[test]
fn test_author_aliases_empty_via_bind() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let id = helpers::add_author(&m, "NoAlias".into(), Some(now));
let aliases = m.bind(id).list_aliases().unwrap();
assert!(aliases.is_empty());
}
#[test]
fn test_author_posts_via_builder() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let author = helpers::add_author(&m, "Writer".into(), Some(now));
let id1 = helpers::add_post(&m, "P1".into(), None, None, Some(now), Some(now));
let id2 = helpers::add_post(&m, "P2".into(), None, None, Some(now), Some(now));
let _id3 = helpers::add_post(&m, "P3-other".into(), None, None, Some(now), Some(now));
helpers::add_post_authors(&m, id1, &[author]);
helpers::add_post_authors(&m, id2, &[author]);
let mut q = m.posts();
q.authors.insert(author);
let posts = q.query::<Post>().unwrap();
assert_eq!(posts.len(), 2);
let ids: Vec<_> = posts.iter().map(|p| p.id).collect();
assert!(ids.contains(&id1));
assert!(ids.contains(&id2));
}
#[test]
fn test_author_posts_empty_via_builder() {
let m = PostArchiverManager::open_in_memory().unwrap();
let now = Utc::now();
let author = helpers::add_author(&m, "Silent".into(), Some(now));
let mut q = m.posts();
q.authors.insert(author);
let posts = q.query::<Post>().unwrap();
assert!(posts.is_empty());
}