refactor(diary): DeleteReviewDeps, GetMovieSocialPageDeps, GetActivityFeedDeps
This commit is contained in:
@@ -12,7 +12,9 @@ use domain::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
diary::commands::DeleteReviewCommand, diary::delete_review, test_helpers::TestContextBuilder,
|
||||
diary::commands::DeleteReviewCommand,
|
||||
diary::delete_review,
|
||||
diary::deps::DeleteReviewDeps,
|
||||
};
|
||||
|
||||
fn make_movie() -> Movie {
|
||||
@@ -51,15 +53,15 @@ async fn test_delete_review_removes_it() {
|
||||
reviews.save_review(&review).await.unwrap();
|
||||
diary.seed_history(movie.clone(), vec![]);
|
||||
|
||||
let ctx = TestContextBuilder::new()
|
||||
.with_movies(Arc::clone(&movies) as _)
|
||||
.with_reviews(Arc::clone(&reviews) as _)
|
||||
.with_diary(Arc::clone(&diary) as _)
|
||||
.with_event_publisher(Arc::clone(&events) as _)
|
||||
.build();
|
||||
let deps = DeleteReviewDeps {
|
||||
review: Arc::clone(&reviews) as _,
|
||||
diary: diary.clone() as _,
|
||||
movie: Arc::clone(&movies) as _,
|
||||
event_publisher: Arc::clone(&events) as _,
|
||||
};
|
||||
|
||||
delete_review::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
DeleteReviewCommand {
|
||||
review_id: review.id().value(),
|
||||
requesting_user_id: user_id.value(),
|
||||
@@ -78,6 +80,9 @@ async fn test_delete_review_removes_it() {
|
||||
#[tokio::test]
|
||||
async fn test_delete_review_wrong_user_is_unauthorized() {
|
||||
let reviews = InMemoryReviewRepository::new();
|
||||
let diary = FakeDiaryRepository::new();
|
||||
let movies = InMemoryMovieRepository::new();
|
||||
let events = NoopEventPublisher::new();
|
||||
|
||||
let movie_id = MovieId::from_uuid(uuid::Uuid::new_v4());
|
||||
let owner_id = UserId::from_uuid(uuid::Uuid::new_v4());
|
||||
@@ -86,12 +91,15 @@ async fn test_delete_review_wrong_user_is_unauthorized() {
|
||||
|
||||
reviews.save_review(&review).await.unwrap();
|
||||
|
||||
let ctx = TestContextBuilder::new()
|
||||
.with_reviews(Arc::clone(&reviews) as _)
|
||||
.build();
|
||||
let deps = DeleteReviewDeps {
|
||||
review: Arc::clone(&reviews) as _,
|
||||
diary: diary as _,
|
||||
movie: movies as _,
|
||||
event_publisher: Arc::clone(&events) as _,
|
||||
};
|
||||
|
||||
let result = delete_review::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
DeleteReviewCommand {
|
||||
review_id: review.id().value(),
|
||||
requesting_user_id: other_id,
|
||||
|
||||
@@ -2,18 +2,30 @@ use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use domain::errors::DomainError;
|
||||
use domain::testing::{FakeDiaryRepository, NoopSocialQueryPort};
|
||||
|
||||
use crate::{
|
||||
diary::get_activity_feed, diary::queries::GetActivityFeedQuery,
|
||||
config::AppConfig,
|
||||
diary::deps::GetActivityFeedDeps,
|
||||
diary::get_activity_feed,
|
||||
diary::queries::GetActivityFeedQuery,
|
||||
test_helpers::TestContextBuilder,
|
||||
};
|
||||
|
||||
fn default_deps() -> GetActivityFeedDeps {
|
||||
GetActivityFeedDeps {
|
||||
diary: FakeDiaryRepository::new() as _,
|
||||
social_query: Arc::new(NoopSocialQueryPort),
|
||||
config: TestContextBuilder::new().config,
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_empty_feed() {
|
||||
let ctx = TestContextBuilder::new().build();
|
||||
let deps = default_deps();
|
||||
|
||||
let result = get_activity_feed::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
GetActivityFeedQuery {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
@@ -32,12 +44,12 @@ async fn returns_empty_feed() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_feed_with_following_filter() {
|
||||
let ctx = TestContextBuilder::new().build();
|
||||
let deps = default_deps();
|
||||
|
||||
let viewer = uuid::Uuid::new_v4();
|
||||
|
||||
let result = get_activity_feed::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
GetActivityFeedQuery {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
@@ -93,12 +105,24 @@ async fn following_filter_parses_local_and_remote_urls() {
|
||||
|
||||
let social = Arc::new(FakeSocialWithFollowing(following_urls));
|
||||
|
||||
let ctx = TestContextBuilder::new()
|
||||
.with_social_query(social as _)
|
||||
.build();
|
||||
let deps = GetActivityFeedDeps {
|
||||
diary: FakeDiaryRepository::new() as _,
|
||||
social_query: social as _,
|
||||
config: AppConfig {
|
||||
allow_registration: true,
|
||||
base_url: "http://localhost:3000".into(),
|
||||
rate_limit: 20,
|
||||
refresh_ttl_seconds: 2_592_000,
|
||||
wrapup: crate::config::WrapUpConfig {
|
||||
font_path: None,
|
||||
logo_path: None,
|
||||
bg_dir: None,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let result = get_activity_feed::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
GetActivityFeedQuery {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
@@ -118,10 +142,10 @@ async fn following_filter_parses_local_and_remote_urls() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn following_filter_without_viewer_returns_none() {
|
||||
let ctx = TestContextBuilder::new().build();
|
||||
let deps = default_deps();
|
||||
|
||||
let result = get_activity_feed::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
GetActivityFeedQuery {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
use crate::{diary::get_diary, diary::queries::GetDiaryQuery, test_helpers::TestContextBuilder};
|
||||
use domain::testing::FakeDiaryRepository;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{diary::get_diary, diary::queries::GetDiaryQuery};
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_empty_page() {
|
||||
let ctx = TestContextBuilder::new().build();
|
||||
let diary = FakeDiaryRepository::new() as Arc<dyn domain::ports::DiaryRepository>;
|
||||
|
||||
let result = get_diary::execute(
|
||||
&ctx,
|
||||
&diary,
|
||||
GetDiaryQuery {
|
||||
limit: None,
|
||||
offset: None,
|
||||
|
||||
@@ -5,21 +5,26 @@ use uuid::Uuid;
|
||||
use domain::{
|
||||
models::Movie,
|
||||
ports::MovieRepository,
|
||||
testing::InMemoryMovieRepository,
|
||||
testing::{FakeDiaryRepository, InMemoryMovieProfileRepository, InMemoryMovieRepository},
|
||||
value_objects::{MovieTitle, ReleaseYear},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
diary::get_movie_social_page, diary::queries::GetMovieSocialPageQuery,
|
||||
test_helpers::TestContextBuilder,
|
||||
diary::deps::GetMovieSocialPageDeps,
|
||||
diary::get_movie_social_page,
|
||||
diary::queries::GetMovieSocialPageQuery,
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn fails_when_movie_not_found() {
|
||||
let ctx = TestContextBuilder::new().build();
|
||||
let deps = GetMovieSocialPageDeps {
|
||||
movie: InMemoryMovieRepository::new(),
|
||||
diary: FakeDiaryRepository::new() as _,
|
||||
movie_profile: InMemoryMovieProfileRepository::new(),
|
||||
};
|
||||
|
||||
let result = get_movie_social_page::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
GetMovieSocialPageQuery {
|
||||
movie_id: Uuid::new_v4(),
|
||||
limit: 10,
|
||||
@@ -45,12 +50,14 @@ async fn returns_movie_social_page() {
|
||||
let movie_uuid = movie.id().value();
|
||||
movies.upsert_movie(&movie).await.unwrap();
|
||||
|
||||
let ctx = TestContextBuilder::new()
|
||||
.with_movies(Arc::clone(&movies) as _)
|
||||
.build();
|
||||
let deps = GetMovieSocialPageDeps {
|
||||
movie: Arc::clone(&movies) as _,
|
||||
diary: FakeDiaryRepository::new() as _,
|
||||
movie_profile: InMemoryMovieProfileRepository::new(),
|
||||
};
|
||||
|
||||
let result = get_movie_social_page::execute(
|
||||
&ctx,
|
||||
&deps,
|
||||
GetMovieSocialPageQuery {
|
||||
movie_id: movie_uuid,
|
||||
limit: 10,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use domain::{
|
||||
models::Movie,
|
||||
ports::DiaryRepository,
|
||||
services::review_history::Trend,
|
||||
value_objects::{MovieTitle, ReleaseYear},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
diary::get_review_history, diary::queries::GetReviewHistoryQuery,
|
||||
test_helpers::TestContextBuilder,
|
||||
};
|
||||
use crate::{diary::get_review_history, diary::queries::GetReviewHistoryQuery};
|
||||
|
||||
#[tokio::test]
|
||||
async fn returns_empty_history() {
|
||||
@@ -22,10 +22,9 @@ async fn returns_empty_history() {
|
||||
|
||||
let diary = domain::testing::FakeDiaryRepository::new();
|
||||
diary.seed_history(movie, vec![]);
|
||||
let diary: Arc<dyn DiaryRepository> = diary;
|
||||
|
||||
let ctx = TestContextBuilder::new().with_diary(diary as _).build();
|
||||
|
||||
let (history, trend) = get_review_history::execute(&ctx, GetReviewHistoryQuery { movie_id })
|
||||
let (history, trend) = get_review_history::execute(&diary, GetReviewHistoryQuery { movie_id })
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -17,24 +17,18 @@ use crate::{
|
||||
test_helpers::TestContextBuilder,
|
||||
};
|
||||
|
||||
fn build_ctx_with_real_logger(
|
||||
fn build_logger(
|
||||
movies: &Arc<InMemoryMovieRepository>,
|
||||
reviews: &Arc<InMemoryReviewRepository>,
|
||||
events: &Arc<NoopEventPublisher>,
|
||||
) -> crate::context::AppContext {
|
||||
let logger = Arc::new(DefaultReviewLogger::new(
|
||||
) -> Arc<dyn crate::ports::ReviewLogger> {
|
||||
Arc::new(DefaultReviewLogger::new(
|
||||
Arc::clone(movies) as _,
|
||||
Arc::clone(reviews) as _,
|
||||
crate::test_helpers::TestContextBuilder::new().watchlist_repo,
|
||||
TestContextBuilder::new().watchlist_repo,
|
||||
Arc::new(domain::testing::FakeMetadataClient) as _,
|
||||
Arc::clone(events) as _,
|
||||
));
|
||||
TestContextBuilder::new()
|
||||
.with_movies(Arc::clone(movies) as _)
|
||||
.with_reviews(Arc::clone(reviews) as _)
|
||||
.with_event_publisher(Arc::clone(events) as _)
|
||||
.with_review_logger(logger)
|
||||
.build()
|
||||
))
|
||||
}
|
||||
|
||||
fn movie_input_manual(title: &str, year: u16) -> MovieInput {
|
||||
@@ -62,7 +56,7 @@ async fn test_log_review_creates_movie_and_review() {
|
||||
let movies = InMemoryMovieRepository::new();
|
||||
let reviews = InMemoryReviewRepository::new();
|
||||
let events = NoopEventPublisher::new();
|
||||
let ctx = build_ctx_with_real_logger(&movies, &reviews, &events);
|
||||
let logger = build_logger(&movies, &reviews, &events);
|
||||
|
||||
let user_id = uuid::Uuid::new_v4();
|
||||
let cmd = LogReviewCommand {
|
||||
@@ -73,7 +67,7 @@ async fn test_log_review_creates_movie_and_review() {
|
||||
watched_at: Utc::now().naive_utc(),
|
||||
};
|
||||
|
||||
log_review::execute(&ctx, cmd).await.unwrap();
|
||||
log_review::execute(&logger, cmd).await.unwrap();
|
||||
|
||||
assert_eq!(reviews.count(), 1, "review should be saved");
|
||||
assert!(!events.published().is_empty(), "events should be published");
|
||||
@@ -95,7 +89,7 @@ async fn test_log_review_reuses_existing_movie() {
|
||||
movies.upsert_movie(&existing_movie).await.unwrap();
|
||||
|
||||
let events = NoopEventPublisher::new();
|
||||
let ctx = build_ctx_with_real_logger(&movies, &reviews, &events);
|
||||
let logger = build_logger(&movies, &reviews, &events);
|
||||
|
||||
let cmd = LogReviewCommand {
|
||||
user_id: uuid::Uuid::new_v4(),
|
||||
@@ -105,7 +99,7 @@ async fn test_log_review_reuses_existing_movie() {
|
||||
watched_at: Utc::now().naive_utc(),
|
||||
};
|
||||
|
||||
log_review::execute(&ctx, cmd).await.unwrap();
|
||||
log_review::execute(&logger, cmd).await.unwrap();
|
||||
|
||||
assert_eq!(movies.count(), 1, "no duplicate movie");
|
||||
assert_eq!(reviews.count(), 1);
|
||||
@@ -116,7 +110,8 @@ async fn test_log_review_with_invalid_rating_fails() {
|
||||
let movies = InMemoryMovieRepository::new();
|
||||
let reviews = InMemoryReviewRepository::new();
|
||||
let events = NoopEventPublisher::new();
|
||||
let ctx = build_ctx_with_real_logger(&movies, &reviews, &events);
|
||||
let logger = build_logger(&movies, &reviews, &events);
|
||||
|
||||
let cmd = LogReviewCommand {
|
||||
user_id: uuid::Uuid::new_v4(),
|
||||
input: movie_input_manual("Some Film", 2000),
|
||||
@@ -124,6 +119,6 @@ async fn test_log_review_with_invalid_rating_fails() {
|
||||
comment: None,
|
||||
watched_at: Utc::now().naive_utc(),
|
||||
};
|
||||
let result = log_review::execute(&ctx, cmd).await;
|
||||
let result = log_review::execute(&logger, cmd).await;
|
||||
assert!(result.is_err(), "rating > 5 should fail");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user