feat(metadata): Implement OMDB metadata provider and refactor metadata client
- Added `OmdbProvider` to fetch movie metadata from the OMDB API. - Refactored `MetadataClient` to use `MetadataSearchCriteria` for fetching movie metadata. - Updated `MetadataClientImpl` to support fetching metadata using OMDB. - Modified `log_review` use case to utilize the new metadata fetching mechanism. - Updated tests and presentation layer to accommodate changes in metadata handling. - Added dependencies for `reqwest` and `async-trait` in relevant `Cargo.toml` files.
This commit is contained in:
@@ -80,7 +80,7 @@ mod tests {
|
||||
}
|
||||
|
||||
struct PanicMeta; struct PanicFetcher; struct PanicStorage; struct PanicEvent; struct PanicHasher; struct PanicAuth; struct PanicUserRepo;
|
||||
#[async_trait::async_trait] impl domain::ports::MetadataClient for PanicMeta { async fn fetch_movie_metadata(&self, _: &domain::value_objects::ExternalMetadataId) -> Result<domain::models::Movie, domain::errors::DomainError> { panic!() } async fn get_poster_url(&self, _: &domain::value_objects::ExternalMetadataId) -> Result<Option<domain::value_objects::PosterUrl>, domain::errors::DomainError> { panic!() } }
|
||||
#[async_trait::async_trait] impl domain::ports::MetadataClient for PanicMeta { async fn fetch_movie_metadata(&self, _: &domain::ports::MetadataSearchCriteria) -> Result<domain::models::Movie, domain::errors::DomainError> { panic!() } async fn get_poster_url(&self, _: &domain::value_objects::ExternalMetadataId) -> Result<Option<domain::value_objects::PosterUrl>, domain::errors::DomainError> { panic!() } }
|
||||
#[async_trait::async_trait] impl domain::ports::PosterFetcherClient for PanicFetcher { async fn fetch_poster_bytes(&self, _: &domain::value_objects::PosterUrl) -> Result<Vec<u8>, domain::errors::DomainError> { panic!() } }
|
||||
#[async_trait::async_trait] impl domain::ports::PosterStorage for PanicStorage { async fn store_poster(&self, _: &domain::value_objects::MovieId, _: &[u8]) -> Result<domain::value_objects::PosterPath, domain::errors::DomainError> { panic!() } async fn get_poster(&self, _: &domain::value_objects::PosterPath) -> Result<Vec<u8>, domain::errors::DomainError> { panic!() } }
|
||||
#[async_trait::async_trait] impl domain::ports::EventPublisher for PanicEvent { async fn publish(&self, _: &domain::events::DomainEvent) -> Result<(), domain::errors::DomainError> { panic!() } }
|
||||
|
||||
@@ -5,9 +5,8 @@ use async_trait::async_trait;
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
events::DomainEvent,
|
||||
models::Movie,
|
||||
ports::{EventPublisher, MetadataClient, PosterFetcherClient, PosterStorage},
|
||||
value_objects::{ExternalMetadataId, MovieId, PosterPath, PosterUrl},
|
||||
ports::{EventPublisher, PosterFetcherClient, PosterStorage},
|
||||
value_objects::{MovieId, PosterPath, PosterUrl},
|
||||
};
|
||||
use sqlx::SqlitePool;
|
||||
use tokio::net::TcpListener;
|
||||
@@ -15,31 +14,12 @@ use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
use application::{config::AppConfig, context::AppContext};
|
||||
use auth::{AuthConfig, Argon2PasswordHasher, JwtAuthService};
|
||||
use metadata::MetadataClientImpl;
|
||||
use sqlite::{SqliteMovieRepository, SqliteUserRepository};
|
||||
use template_askama::AskamaHtmlRenderer;
|
||||
|
||||
use presentation::{routes, state::AppState};
|
||||
|
||||
struct StubMetadataClient;
|
||||
|
||||
#[async_trait]
|
||||
impl MetadataClient for StubMetadataClient {
|
||||
async fn fetch_movie_metadata(&self, _id: &ExternalMetadataId) -> Result<Movie, DomainError> {
|
||||
Err(DomainError::InfrastructureError(
|
||||
"metadata client not implemented".into(),
|
||||
))
|
||||
}
|
||||
|
||||
async fn get_poster_url(
|
||||
&self,
|
||||
_id: &ExternalMetadataId,
|
||||
) -> Result<Option<PosterUrl>, DomainError> {
|
||||
Err(DomainError::InfrastructureError(
|
||||
"metadata client not implemented".into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
struct StubPosterFetcher;
|
||||
|
||||
#[async_trait]
|
||||
@@ -102,6 +82,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
async fn wire_dependencies() -> anyhow::Result<AppState> {
|
||||
let auth_config = AuthConfig::from_env()?;
|
||||
let app_config = AppConfig::from_env();
|
||||
let omdb_api_key = std::env::var("OMDB_API_KEY").context("OMDB_API_KEY must be set")?;
|
||||
|
||||
let pool = SqlitePool::connect("sqlite://reviews.db")
|
||||
.await
|
||||
@@ -118,7 +99,7 @@ async fn wire_dependencies() -> anyhow::Result<AppState> {
|
||||
|
||||
let app_ctx = AppContext {
|
||||
repository: Arc::new(movie_repo),
|
||||
metadata_client: Arc::new(StubMetadataClient),
|
||||
metadata_client: Arc::new(MetadataClientImpl::new_omdb(omdb_api_key)),
|
||||
poster_fetcher: Arc::new(StubPosterFetcher),
|
||||
poster_storage: Arc::new(StubPosterStorage),
|
||||
event_publisher: Arc::new(StubEventPublisher),
|
||||
|
||||
Reference in New Issue
Block a user