160 lines
4.5 KiB
Rust
160 lines
4.5 KiB
Rust
use chrono::NaiveDate;
|
|
use domain::models::wrapup::{DateRange, WrapUpScope};
|
|
use domain::ports::WrapUpMovieRow;
|
|
use domain::testing::InMemoryWrapUpStatsQuery;
|
|
use uuid::Uuid;
|
|
|
|
use crate::test_helpers::TestContextBuilder;
|
|
use crate::wrapup::queries::ComputeWrapUpQuery;
|
|
|
|
fn make_row(title: &str, rating: u8, watched_at: &str) -> WrapUpMovieRow {
|
|
WrapUpMovieRow {
|
|
movie_id: Uuid::new_v4(),
|
|
title: title.to_string(),
|
|
release_year: 2024,
|
|
director: Some("Director".to_string()),
|
|
poster_path: None,
|
|
rating,
|
|
watched_at: chrono::NaiveDateTime::parse_from_str(
|
|
&format!("{watched_at} 20:00:00"),
|
|
"%Y-%m-%d %H:%M:%S",
|
|
)
|
|
.unwrap(),
|
|
user_id: Uuid::new_v4(),
|
|
runtime_minutes: Some(120),
|
|
budget_usd: Some(50_000_000),
|
|
original_language: Some("en".to_string()),
|
|
genres: vec!["Action".to_string()],
|
|
keywords: vec!["heist".to_string()],
|
|
cast_names: vec![("Actor A".to_string(), 1)],
|
|
cast_profile_paths: vec![None],
|
|
}
|
|
}
|
|
|
|
fn year_2024_range() -> DateRange {
|
|
DateRange::new(
|
|
NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(),
|
|
NaiveDate::from_ymd_opt(2025, 1, 1).unwrap(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn empty_report() {
|
|
let stats = InMemoryWrapUpStatsQuery::new();
|
|
let ctx = TestContextBuilder::new().wrapup_stats(stats).build();
|
|
let user_id = Uuid::new_v4();
|
|
|
|
let report = super::execute(
|
|
&ctx,
|
|
ComputeWrapUpQuery {
|
|
scope: WrapUpScope::User(user_id),
|
|
date_range: year_2024_range(),
|
|
},
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(report.total_movies, 0);
|
|
assert!(report.avg_rating.is_none());
|
|
assert_eq!(report.rating_distribution, [0; 5]);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn basic_stats() {
|
|
let user_id = Uuid::new_v4();
|
|
let mut r1 = make_row("Film A", 4, "2024-03-10");
|
|
r1.user_id = user_id;
|
|
r1.runtime_minutes = Some(120);
|
|
r1.genres = vec!["Action".to_string()];
|
|
|
|
let mut r2 = make_row("Film B", 2, "2024-03-20");
|
|
r2.user_id = user_id;
|
|
r2.runtime_minutes = Some(90);
|
|
r2.genres = vec!["Comedy".to_string()];
|
|
|
|
let stats = InMemoryWrapUpStatsQuery::with_rows(vec![r1, r2]);
|
|
let ctx = TestContextBuilder::new().wrapup_stats(stats).build();
|
|
|
|
let report = super::execute(
|
|
&ctx,
|
|
ComputeWrapUpQuery {
|
|
scope: WrapUpScope::User(user_id),
|
|
date_range: year_2024_range(),
|
|
},
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(report.total_movies, 2);
|
|
assert_eq!(report.total_watch_time_minutes, 210);
|
|
assert!((report.avg_rating.unwrap() - 3.0).abs() < f64::EPSILON);
|
|
assert_eq!(report.rating_distribution, [0, 1, 0, 1, 0]);
|
|
assert_eq!(report.busiest_month.as_deref(), Some("March 2024"));
|
|
assert_eq!(report.director_diversity, 1);
|
|
assert_eq!(report.genre_diversity, 2);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn rewatch_detection() {
|
|
let user_id = Uuid::new_v4();
|
|
let movie_id = Uuid::new_v4();
|
|
|
|
let mut r1 = make_row("Film A", 3, "2024-02-01");
|
|
r1.user_id = user_id;
|
|
r1.movie_id = movie_id;
|
|
|
|
let mut r2 = make_row("Film A", 5, "2024-06-01");
|
|
r2.user_id = user_id;
|
|
r2.movie_id = movie_id;
|
|
|
|
let stats = InMemoryWrapUpStatsQuery::with_rows(vec![r1, r2]);
|
|
let ctx = TestContextBuilder::new().wrapup_stats(stats).build();
|
|
|
|
let report = super::execute(
|
|
&ctx,
|
|
ComputeWrapUpQuery {
|
|
scope: WrapUpScope::User(user_id),
|
|
date_range: year_2024_range(),
|
|
},
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(report.total_rewatches, 1);
|
|
assert_eq!(
|
|
report.most_rewatched_movie.as_ref().unwrap().title,
|
|
"Film A"
|
|
);
|
|
assert!((report.avg_rating_change_on_rewatch.unwrap() - 2.0).abs() < f64::EPSILON);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn global_scope() {
|
|
let user_a = Uuid::new_v4();
|
|
let user_b = Uuid::new_v4();
|
|
|
|
let mut r1 = make_row("Film X", 4, "2024-05-01");
|
|
r1.user_id = user_a;
|
|
|
|
let mut r2 = make_row("Film Y", 3, "2024-07-01");
|
|
r2.user_id = user_b;
|
|
|
|
let stats = InMemoryWrapUpStatsQuery::with_rows(vec![r1, r2]);
|
|
let ctx = TestContextBuilder::new().wrapup_stats(stats).build();
|
|
|
|
let report = super::execute(
|
|
&ctx,
|
|
ComputeWrapUpQuery {
|
|
scope: WrapUpScope::Global,
|
|
date_range: year_2024_range(),
|
|
},
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert_eq!(report.total_movies, 2);
|
|
assert_eq!(report.total_users_active, Some(2));
|
|
assert!(report.most_active_user.is_some());
|
|
}
|