use chrono::NaiveDate; use uuid::Uuid; use crate::models::WrapUpMovieRow; use crate::models::wrapup::{DateRange, WrapUpScope}; use super::super::wrapup_analyzer::build_report; fn row(title: &str, rating: u8, ym: &str) -> WrapUpMovieRow { WrapUpMovieRow { movie_id: Uuid::new_v4(), title: title.to_string(), release_year: 2024, director: Some("Dir".to_string()), poster_path: None, rating, watched_at: chrono::NaiveDateTime::parse_from_str( &format!("{ym}-01 12:00:00"), "%Y-%m-%d %H:%M:%S", ) .unwrap(), user_id: Uuid::new_v4(), runtime_minutes: Some(100), budget_usd: None, original_language: Some("en".to_string()), watch_medium: None, genres: vec!["Action".to_string()], keywords: vec![], cast_names: vec![], cast_profile_paths: vec![], } } fn range() -> DateRange { DateRange::new( NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(), NaiveDate::from_ymd_opt(2025, 1, 1).unwrap(), ) .unwrap() } #[test] fn empty_rows_returns_zero_totals() { let report = build_report(WrapUpScope::Global, range(), &[]); assert_eq!(report.total_movies, 0); assert!(report.avg_rating.is_none()); assert_eq!(report.rating_distribution, [0u32; 5]); } #[test] fn total_movies_matches_row_count() { let rows = vec![row("A", 5, "2024-01"), row("B", 3, "2024-02")]; let report = build_report(WrapUpScope::Global, range(), &rows); assert_eq!(report.total_movies, 2); } #[test] fn avg_rating_is_correct() { let rows = vec![row("A", 4, "2024-01"), row("B", 2, "2024-01")]; let report = build_report(WrapUpScope::Global, range(), &rows); let avg = report.avg_rating.unwrap(); assert!((avg - 3.0).abs() < f64::EPSILON); } #[test] fn rating_distribution_counts_correctly() { let rows = vec![ row("A", 5, "2024-01"), row("B", 5, "2024-02"), row("C", 3, "2024-03"), ]; let report = build_report(WrapUpScope::Global, range(), &rows); assert_eq!(report.rating_distribution[4], 2); assert_eq!(report.rating_distribution[2], 1); } #[test] fn movies_per_month_sorted_chronologically() { let rows = vec![ row("A", 3, "2024-03"), row("B", 3, "2024-01"), row("C", 3, "2024-02"), ]; let report = build_report(WrapUpScope::Global, range(), &rows); let yms: Vec<&str> = report .movies_per_month .iter() .map(|m| m.year_month.as_str()) .collect(); assert_eq!(yms, ["2024-01", "2024-02", "2024-03"]); } #[test] fn global_scope_populates_global_fields() { let rows = vec![row("A", 4, "2024-01")]; let report = build_report(WrapUpScope::Global, range(), &rows); assert!(report.total_users_active.is_some()); } #[test] fn user_scope_leaves_global_fields_empty() { let rows = vec![row("A", 4, "2024-01")]; let report = build_report(WrapUpScope::User(Uuid::new_v4()), range(), &rows); assert!(report.total_users_active.is_none()); assert!(report.most_active_user.is_none()); }