use std::sync::Arc; use uuid::Uuid; use domain::{ errors::DomainError, models::Movie, ports::{MetadataClient, MovieRepository}, testing::{InMemoryMovieProfileRepository, InMemoryMovieRepository, NoopEventPublisher, NoopObjectStorage, FakeSearchCommand}, value_objects::{ExternalMetadataId, MovieTitle, PosterUrl, ReleaseYear}, }; use crate::{ diary::commands::SyncPosterCommand, movies::{deps::SyncPosterDeps, sync_poster}, }; fn default_deps() -> SyncPosterDeps { SyncPosterDeps { movie: InMemoryMovieRepository::new(), movie_profile: InMemoryMovieProfileRepository::new(), metadata: Arc::new(domain::testing::FakeMetadataClient), poster_fetcher: Arc::new(domain::testing::FakePosterFetcher), object_storage: Arc::new(NoopObjectStorage), event_publisher: NoopEventPublisher::new(), search_command: Arc::new(FakeSearchCommand), } } #[tokio::test] async fn fails_when_movie_not_found() { let deps = default_deps(); let result = sync_poster::execute( &deps, SyncPosterCommand { movie_id: Uuid::new_v4(), }, ) .await; assert!(result.is_err()); } #[tokio::test] async fn fails_when_no_external_id() { let movies = InMemoryMovieRepository::new(); let movie = Movie::new( None, MovieTitle::new("Test".into()).unwrap(), ReleaseYear::new(2024).unwrap(), None, None, ); let movie_id = movie.id().value(); movies.upsert_movie(&movie).await.unwrap(); let deps = SyncPosterDeps { movie: Arc::clone(&movies) as _, ..default_deps() }; let result = sync_poster::execute(&deps, SyncPosterCommand { movie_id }).await; assert!(result.is_err()); } struct FakeMetaWithPoster; #[async_trait::async_trait] impl MetadataClient for FakeMetaWithPoster { async fn fetch_movie_metadata( &self, _: &domain::ports::MetadataSearchCriteria, ) -> Result { unimplemented!() } async fn get_poster_url( &self, _: &ExternalMetadataId, ) -> Result, DomainError> { Ok(Some( PosterUrl::new("https://example.com/poster.jpg".into()).unwrap(), )) } } #[tokio::test] async fn syncs_poster_for_movie_with_external_id() { let movies = InMemoryMovieRepository::new(); let ext_id = ExternalMetadataId::new("tmdb:999".into()).unwrap(); let movie = Movie::new( Some(ext_id), MovieTitle::new("Poster Movie".into()).unwrap(), ReleaseYear::new(2024).unwrap(), None, None, ); let movie_id = movie.id().value(); movies.upsert_movie(&movie).await.unwrap(); let deps = SyncPosterDeps { movie: Arc::clone(&movies) as _, metadata: Arc::new(FakeMetaWithPoster) as _, ..default_deps() }; sync_poster::execute(&deps, SyncPosterCommand { movie_id }) .await .unwrap(); let updated = movies .get_movie_by_id(&domain::value_objects::MovieId::from_uuid(movie_id)) .await .unwrap() .unwrap(); assert!(updated.poster_path().is_some()); }