This commit is contained in:
@@ -28,7 +28,12 @@ where
|
||||
"Missing or invalid auth token".into(),
|
||||
))
|
||||
})?;
|
||||
let user_id = app_state.app_ctx.auth_service.validate_token(token).await?;
|
||||
let user_id = app_state
|
||||
.app_ctx
|
||||
.services
|
||||
.auth
|
||||
.validate_token(token)
|
||||
.await?;
|
||||
Ok(AuthenticatedUser(user_id))
|
||||
}
|
||||
}
|
||||
@@ -62,7 +67,8 @@ where
|
||||
};
|
||||
let user_id = app_state
|
||||
.app_ctx
|
||||
.auth_service
|
||||
.services
|
||||
.auth
|
||||
.validate_token(&token)
|
||||
.await
|
||||
.ok();
|
||||
@@ -83,7 +89,8 @@ where
|
||||
.ok_or_else(|| Redirect::to("/login").into_response())?;
|
||||
let user_id = app_state
|
||||
.app_ctx
|
||||
.auth_service
|
||||
.services
|
||||
.auth
|
||||
.validate_token(&token)
|
||||
.await
|
||||
.map_err(|_| Redirect::to("/login").into_response())?;
|
||||
@@ -106,7 +113,8 @@ where
|
||||
RequiredCookieUser::from_request_parts(parts, state).await?;
|
||||
let user = app_state
|
||||
.app_ctx
|
||||
.user_repository
|
||||
.repos
|
||||
.user
|
||||
.find_by_id(&user_id)
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR.into_response())?
|
||||
|
||||
@@ -1,36 +1,11 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Context;
|
||||
|
||||
use domain::ports::{
|
||||
AuthService, DiaryRepository, ImageStorage, ImportProfileRepository, ImportSessionRepository,
|
||||
LocalApContentQuery, MetadataClient, MovieProfileRepository, MovieRepository, PasswordHasher,
|
||||
PersonCommand, PersonQuery, PosterFetcherClient, ReviewRepository, SearchCommand, SearchPort,
|
||||
StatsRepository, UserProfileFieldsRepository, UserRepository, WatchEventRepository,
|
||||
WatchlistRepository, WebhookTokenRepository,
|
||||
AuthService, ImageStorage, LocalApContentQuery, MetadataClient, PasswordHasher,
|
||||
PosterFetcherClient, UserProfileFieldsRepository, WatchEventRepository, WebhookTokenRepository,
|
||||
};
|
||||
|
||||
pub struct DatabaseAdapters {
|
||||
pub movie_repo: Arc<dyn MovieRepository>,
|
||||
pub review_repo: Arc<dyn ReviewRepository>,
|
||||
pub diary_repo: Arc<dyn DiaryRepository>,
|
||||
pub stats_repo: Arc<dyn StatsRepository>,
|
||||
pub user_repo: Arc<dyn UserRepository>,
|
||||
pub import_session_repo: Arc<dyn ImportSessionRepository>,
|
||||
pub import_profile_repo: Arc<dyn ImportProfileRepository>,
|
||||
pub movie_profile_repo: Arc<dyn MovieProfileRepository>,
|
||||
pub watchlist_repo: Arc<dyn WatchlistRepository>,
|
||||
pub ap_content_repo: Arc<dyn LocalApContentQuery>,
|
||||
pub person_command: Arc<dyn PersonCommand>,
|
||||
pub person_query: Arc<dyn PersonQuery>,
|
||||
pub search_port: Arc<dyn SearchPort>,
|
||||
pub search_command: Arc<dyn SearchCommand>,
|
||||
pub profile_fields_repo: Arc<dyn UserProfileFieldsRepository>,
|
||||
pub watch_event_repo: Arc<dyn WatchEventRepository>,
|
||||
pub webhook_token_repo: Arc<dyn WebhookTokenRepository>,
|
||||
pub db_pool: DbPool,
|
||||
}
|
||||
|
||||
pub enum DbPool {
|
||||
#[cfg(feature = "sqlite")]
|
||||
Sqlite(sqlx::SqlitePool),
|
||||
@@ -38,72 +13,94 @@ pub enum DbPool {
|
||||
Postgres(sqlx::PgPool),
|
||||
}
|
||||
|
||||
pub async fn build_database_adapters(backend: &str, url: &str) -> anyhow::Result<DatabaseAdapters> {
|
||||
pub struct DatabaseOutput {
|
||||
pub movie: Arc<dyn domain::ports::MovieRepository>,
|
||||
pub review: Arc<dyn domain::ports::ReviewRepository>,
|
||||
pub diary: Arc<dyn domain::ports::DiaryRepository>,
|
||||
pub stats: Arc<dyn domain::ports::StatsRepository>,
|
||||
pub user: Arc<dyn domain::ports::UserRepository>,
|
||||
pub import_session: Arc<dyn domain::ports::ImportSessionRepository>,
|
||||
pub import_profile: Arc<dyn domain::ports::ImportProfileRepository>,
|
||||
pub movie_profile: Arc<dyn domain::ports::MovieProfileRepository>,
|
||||
pub watchlist: Arc<dyn domain::ports::WatchlistRepository>,
|
||||
pub watch_event: Arc<dyn WatchEventRepository>,
|
||||
pub webhook_token: Arc<dyn WebhookTokenRepository>,
|
||||
pub person_command: Arc<dyn domain::ports::PersonCommand>,
|
||||
pub person_query: Arc<dyn domain::ports::PersonQuery>,
|
||||
pub search_port: Arc<dyn domain::ports::SearchPort>,
|
||||
pub search_command: Arc<dyn domain::ports::SearchCommand>,
|
||||
pub profile_fields: Arc<dyn UserProfileFieldsRepository>,
|
||||
pub ap_content: Arc<dyn LocalApContentQuery>,
|
||||
pub db_pool: DbPool,
|
||||
}
|
||||
|
||||
pub async fn build_database_adapters(backend: &str, url: &str) -> anyhow::Result<DatabaseOutput> {
|
||||
match backend {
|
||||
#[cfg(feature = "postgres")]
|
||||
"postgres" => {
|
||||
let (pool, m, r, d, s, u, is, ip, mp, wl, ac) = postgres::wire(url)
|
||||
let w = postgres::wire(url)
|
||||
.await
|
||||
.context("PostgreSQL connection failed")?;
|
||||
let (pc, pq) = postgres::create_person_adapter(pool.clone());
|
||||
let (sc, sp) = postgres_search::create_search_adapter(pool.clone());
|
||||
let pf = postgres::create_profile_fields_repo(pool.clone());
|
||||
let (pc, pq) = postgres::create_person_adapter(w.pool.clone());
|
||||
let (sc, sp) = postgres_search::create_search_adapter(w.pool.clone());
|
||||
let pf = postgres::create_profile_fields_repo(w.pool.clone());
|
||||
let we: Arc<dyn WatchEventRepository> =
|
||||
Arc::new(postgres::PostgresWatchEventRepository::new(pool.clone()));
|
||||
let wt: Arc<dyn WebhookTokenRepository> =
|
||||
Arc::new(postgres::PostgresWebhookTokenRepository::new(pool.clone()));
|
||||
Ok(DatabaseAdapters {
|
||||
movie_repo: m,
|
||||
review_repo: r,
|
||||
diary_repo: d,
|
||||
stats_repo: s,
|
||||
user_repo: u,
|
||||
import_session_repo: is,
|
||||
import_profile_repo: ip,
|
||||
movie_profile_repo: mp,
|
||||
watchlist_repo: wl,
|
||||
ap_content_repo: ac,
|
||||
Arc::new(postgres::PostgresWatchEventRepository::new(w.pool.clone()));
|
||||
let wt: Arc<dyn WebhookTokenRepository> = Arc::new(
|
||||
postgres::PostgresWebhookTokenRepository::new(w.pool.clone()),
|
||||
);
|
||||
Ok(DatabaseOutput {
|
||||
movie: w.movie,
|
||||
review: w.review,
|
||||
diary: w.diary,
|
||||
stats: w.stats,
|
||||
user: w.user,
|
||||
import_session: w.import_session,
|
||||
import_profile: w.import_profile,
|
||||
movie_profile: w.movie_profile,
|
||||
watchlist: w.watchlist,
|
||||
watch_event: we,
|
||||
webhook_token: wt,
|
||||
person_command: pc,
|
||||
person_query: pq,
|
||||
search_port: sp,
|
||||
search_command: sc,
|
||||
profile_fields_repo: pf,
|
||||
watch_event_repo: we,
|
||||
webhook_token_repo: wt,
|
||||
db_pool: DbPool::Postgres(pool),
|
||||
profile_fields: pf,
|
||||
ap_content: w.ap_content,
|
||||
db_pool: DbPool::Postgres(w.pool),
|
||||
})
|
||||
}
|
||||
#[cfg(feature = "sqlite")]
|
||||
_ => {
|
||||
let (pool, m, r, d, s, u, is, ip, mp, wl, ac) = sqlite::wire(url)
|
||||
let w = sqlite::wire(url)
|
||||
.await
|
||||
.context("SQLite connection failed")?;
|
||||
let (pc, pq) = sqlite::create_person_adapter(pool.clone());
|
||||
let (sc, sp) = sqlite_search::create_search_adapter(pool.clone());
|
||||
let pf = sqlite::create_profile_fields_repo(pool.clone());
|
||||
let (pc, pq) = sqlite::create_person_adapter(w.pool.clone());
|
||||
let (sc, sp) = sqlite_search::create_search_adapter(w.pool.clone());
|
||||
let pf = sqlite::create_profile_fields_repo(w.pool.clone());
|
||||
let we: Arc<dyn WatchEventRepository> =
|
||||
Arc::new(sqlite::SqliteWatchEventRepository::new(pool.clone()));
|
||||
Arc::new(sqlite::SqliteWatchEventRepository::new(w.pool.clone()));
|
||||
let wt: Arc<dyn WebhookTokenRepository> =
|
||||
Arc::new(sqlite::SqliteWebhookTokenRepository::new(pool.clone()));
|
||||
Ok(DatabaseAdapters {
|
||||
movie_repo: m,
|
||||
review_repo: r,
|
||||
diary_repo: d,
|
||||
stats_repo: s,
|
||||
user_repo: u,
|
||||
import_session_repo: is,
|
||||
import_profile_repo: ip,
|
||||
movie_profile_repo: mp,
|
||||
watchlist_repo: wl,
|
||||
ap_content_repo: ac,
|
||||
Arc::new(sqlite::SqliteWebhookTokenRepository::new(w.pool.clone()));
|
||||
Ok(DatabaseOutput {
|
||||
movie: w.movie,
|
||||
review: w.review,
|
||||
diary: w.diary,
|
||||
stats: w.stats,
|
||||
user: w.user,
|
||||
import_session: w.import_session,
|
||||
import_profile: w.import_profile,
|
||||
movie_profile: w.movie_profile,
|
||||
watchlist: w.watchlist,
|
||||
watch_event: we,
|
||||
webhook_token: wt,
|
||||
person_command: pc,
|
||||
person_query: pq,
|
||||
search_port: sp,
|
||||
search_command: sc,
|
||||
profile_fields_repo: pf,
|
||||
watch_event_repo: we,
|
||||
webhook_token_repo: wt,
|
||||
db_pool: DbPool::Sqlite(pool),
|
||||
profile_fields: pf,
|
||||
ap_content: w.ap_content,
|
||||
db_pool: DbPool::Sqlite(w.pool),
|
||||
})
|
||||
}
|
||||
#[cfg(not(feature = "sqlite"))]
|
||||
|
||||
@@ -13,7 +13,7 @@ pub async fn get_image(
|
||||
if key.starts_with("http://") || key.starts_with("https://") {
|
||||
return axum::response::Redirect::temporary(&key).into_response();
|
||||
}
|
||||
match state.app_ctx.image_storage.get(&key).await {
|
||||
match state.app_ctx.services.image_storage.get(&key).await {
|
||||
Ok(bytes) => {
|
||||
let mime = infer::get(&bytes)
|
||||
.map(|t| t.mime_type())
|
||||
|
||||
@@ -6,6 +6,7 @@ pub mod forms;
|
||||
pub mod handlers;
|
||||
pub mod openapi;
|
||||
pub mod ports;
|
||||
pub mod render;
|
||||
pub mod routes;
|
||||
pub mod state;
|
||||
|
||||
|
||||
@@ -5,13 +5,14 @@ use anyhow::Context;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
use application::{config::AppConfig, context::AppContext};
|
||||
use application::{
|
||||
config::AppConfig,
|
||||
context::{AppContext, Repositories, Services},
|
||||
};
|
||||
use export::ExportAdapter;
|
||||
use importer::ImporterDocumentParser;
|
||||
use rss::RssAdapter;
|
||||
use template_askama::AskamaHtmlRenderer;
|
||||
|
||||
use presentation::{factory, openapi, routes, state::AppState};
|
||||
use rss::RssAdapter;
|
||||
|
||||
use domain::ports::{DiaryExporter, DocumentParser, EventPublisher};
|
||||
|
||||
@@ -59,24 +60,7 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
|
||||
let image_storage = factory::build_image_storage()?;
|
||||
|
||||
let db = factory::build_database_adapters(&backend, &database_url).await?;
|
||||
|
||||
let movie_repository = db.movie_repo;
|
||||
let review_repository = db.review_repo;
|
||||
let diary_repository = db.diary_repo;
|
||||
let stats_repository = db.stats_repo;
|
||||
let user_repository = db.user_repo;
|
||||
let import_session_repository = db.import_session_repo;
|
||||
let import_profile_repository = db.import_profile_repo;
|
||||
let movie_profile_repository = db.movie_profile_repo;
|
||||
let watchlist_repository = db.watchlist_repo;
|
||||
let ap_content_repo = db.ap_content_repo;
|
||||
let person_command = db.person_command;
|
||||
let person_query = db.person_query;
|
||||
let search_port = db.search_port;
|
||||
let search_command = db.search_command;
|
||||
let profile_fields_repo = db.profile_fields_repo;
|
||||
let watch_event_repository = db.watch_event_repo;
|
||||
let webhook_token_repository = db.webhook_token_repo;
|
||||
let ap_content_repo = db.ap_content;
|
||||
let db_pool = db.db_pool;
|
||||
|
||||
// Wire up event channel, federation service, and ap_router
|
||||
@@ -135,7 +119,7 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
|
||||
review_store,
|
||||
remote_watchlist_repo: remote_watchlist_repo.clone(),
|
||||
local_ap_content: Arc::clone(&ap_content_repo),
|
||||
user_repo: Arc::clone(&user_repository),
|
||||
user_repo: Arc::clone(&db.user),
|
||||
base_url: app_config.base_url.clone(),
|
||||
allow_registration: app_config.allow_registration,
|
||||
event_publisher: Arc::clone(&ep),
|
||||
@@ -184,40 +168,43 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
|
||||
let ap_router = axum::Router::new();
|
||||
|
||||
let app_ctx = AppContext {
|
||||
movie_repository,
|
||||
review_repository,
|
||||
diary_repository,
|
||||
diary_exporter: Arc::new(ExportAdapter) as Arc<dyn DiaryExporter>,
|
||||
document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>,
|
||||
stats_repository,
|
||||
metadata_client,
|
||||
poster_fetcher,
|
||||
image_storage,
|
||||
event_publisher: event_publisher_arc,
|
||||
auth_service,
|
||||
password_hasher,
|
||||
user_repository,
|
||||
import_session_repository,
|
||||
import_profile_repository,
|
||||
movie_profile_repository,
|
||||
watchlist_repository,
|
||||
watch_event_repository,
|
||||
webhook_token_repository,
|
||||
profile_fields_repository: profile_fields_repo,
|
||||
#[cfg(feature = "federation")]
|
||||
remote_watchlist_repository: remote_watchlist_repo,
|
||||
#[cfg(feature = "federation")]
|
||||
social_query: social_query.clone(),
|
||||
person_command,
|
||||
person_query,
|
||||
search_port,
|
||||
search_command,
|
||||
repos: Repositories {
|
||||
movie: db.movie,
|
||||
review: db.review,
|
||||
diary: db.diary,
|
||||
stats: db.stats,
|
||||
user: db.user,
|
||||
import_session: db.import_session,
|
||||
import_profile: db.import_profile,
|
||||
movie_profile: db.movie_profile,
|
||||
watchlist: db.watchlist,
|
||||
watch_event: db.watch_event,
|
||||
webhook_token: db.webhook_token,
|
||||
person_command: db.person_command,
|
||||
person_query: db.person_query,
|
||||
search_port: db.search_port,
|
||||
search_command: db.search_command,
|
||||
profile_fields: db.profile_fields,
|
||||
#[cfg(feature = "federation")]
|
||||
remote_watchlist: remote_watchlist_repo,
|
||||
#[cfg(feature = "federation")]
|
||||
social_query: social_query.clone(),
|
||||
},
|
||||
services: Services {
|
||||
auth: auth_service,
|
||||
password_hasher,
|
||||
metadata: metadata_client,
|
||||
poster_fetcher,
|
||||
image_storage,
|
||||
event_publisher: event_publisher_arc,
|
||||
diary_exporter: Arc::new(ExportAdapter) as Arc<dyn DiaryExporter>,
|
||||
document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>,
|
||||
},
|
||||
config: app_config,
|
||||
};
|
||||
|
||||
let state = AppState {
|
||||
app_ctx,
|
||||
html_renderer: Arc::new(AskamaHtmlRenderer::new()),
|
||||
rss_renderer: Arc::new(RssAdapter::new(
|
||||
std::env::var("BASE_URL").unwrap_or_else(|_| "http://localhost:3000".into()),
|
||||
)),
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
pub use application::ports::HtmlRenderer;
|
||||
pub use application::ports::RssFeedRenderer;
|
||||
|
||||
14
crates/presentation/src/render.rs
Normal file
14
crates/presentation/src/render.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use axum::{
|
||||
http::StatusCode,
|
||||
response::{Html, IntoResponse, Response},
|
||||
};
|
||||
|
||||
pub fn render_page(template: impl template_askama::askama::Template) -> Response {
|
||||
match template.render() {
|
||||
Ok(html) => Html(html).into_response(),
|
||||
Err(e) => {
|
||||
tracing::error!("template error: {e}");
|
||||
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,11 @@ use std::sync::Arc;
|
||||
|
||||
use application::context::AppContext;
|
||||
|
||||
use crate::ports::{HtmlRenderer, RssFeedRenderer};
|
||||
use crate::ports::RssFeedRenderer;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub app_ctx: AppContext,
|
||||
pub html_renderer: Arc<dyn HtmlRenderer>,
|
||||
pub rss_renderer: Arc<dyn RssFeedRenderer>,
|
||||
#[cfg(feature = "federation")]
|
||||
pub ap_service: Arc<dyn activitypub::ActivityPubPort>,
|
||||
|
||||
@@ -68,7 +68,7 @@ impl domain::ports::PersonQuery for PersonQueryStub {
|
||||
async fn search_endpoint_returns_200_with_empty_results() {
|
||||
let mut state = make_test_state(Arc::new(Panic));
|
||||
// Override the search_port with our stub
|
||||
state.app_ctx.search_port = Arc::new(SearchPortStub);
|
||||
state.app_ctx.repos.search_port = Arc::new(SearchPortStub);
|
||||
let app = Router::new()
|
||||
.route("/api/v1/search", get(crate::handlers::api::get_search))
|
||||
.with_state(state);
|
||||
@@ -90,7 +90,7 @@ async fn search_endpoint_returns_200_with_empty_results() {
|
||||
async fn search_endpoint_with_no_query_returns_200() {
|
||||
let mut state = make_test_state(Arc::new(Panic));
|
||||
// Override the search_port with our stub
|
||||
state.app_ctx.search_port = Arc::new(SearchPortStub);
|
||||
state.app_ctx.repos.search_port = Arc::new(SearchPortStub);
|
||||
let app = Router::new()
|
||||
.route("/api/v1/search", get(crate::handlers::api::get_search))
|
||||
.with_state(state);
|
||||
@@ -114,7 +114,7 @@ async fn search_endpoint_with_no_query_returns_200() {
|
||||
async fn person_endpoint_returns_404_for_unknown_id() {
|
||||
let mut state = make_test_state(Arc::new(Panic));
|
||||
// Override the person_query with our stub
|
||||
state.app_ctx.person_query = Arc::new(PersonQueryStub);
|
||||
state.app_ctx.repos.person_query = Arc::new(PersonQueryStub);
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/api/v1/people/{id}",
|
||||
@@ -140,7 +140,7 @@ async fn person_endpoint_returns_404_for_unknown_id() {
|
||||
async fn person_credits_endpoint_returns_404_for_unknown_id() {
|
||||
let mut state = make_test_state(Arc::new(Panic));
|
||||
// Override the person_query with our stub
|
||||
state.app_ctx.person_query = Arc::new(PersonQueryStub);
|
||||
state.app_ctx.repos.person_query = Arc::new(PersonQueryStub);
|
||||
let app = Router::new()
|
||||
.route(
|
||||
"/api/v1/people/{id}/credits",
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use super::*;
|
||||
use application::{config::AppConfig, context::AppContext};
|
||||
use application::{
|
||||
config::AppConfig,
|
||||
context::{AppContext, Repositories, Services},
|
||||
};
|
||||
use axum::{
|
||||
Router,
|
||||
body::Body,
|
||||
@@ -387,120 +390,6 @@ impl domain::ports::DocumentParser for Panic {
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::ports::HtmlRenderer for Panic {
|
||||
fn render_diary_page(
|
||||
&self,
|
||||
_: &Paginated<DiaryEntry>,
|
||||
_: application::ports::HtmlPageContext,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_login_page(
|
||||
&self,
|
||||
_: application::ports::LoginPageData<'_>,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_register_page(
|
||||
&self,
|
||||
_: application::ports::RegisterPageData<'_>,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_new_review_page(
|
||||
&self,
|
||||
_: application::ports::NewReviewPageData<'_>,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_activity_feed_page(
|
||||
&self,
|
||||
_: application::ports::ActivityFeedPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_users_page(&self, _: application::ports::UsersPageData) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_profile_page(
|
||||
&self,
|
||||
_: application::ports::ProfilePageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_following_page(
|
||||
&self,
|
||||
_: application::ports::FollowingPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_followers_page(
|
||||
&self,
|
||||
_: application::ports::FollowersPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_movie_detail_page(
|
||||
&self,
|
||||
_: application::ports::MovieDetailPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_import_upload_page(
|
||||
&self,
|
||||
_: application::ports::ImportUploadPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_import_mapping_page(
|
||||
&self,
|
||||
_: application::ports::ImportMappingPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_import_preview_page(
|
||||
&self,
|
||||
_: application::ports::ImportPreviewPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_profile_settings_page(
|
||||
&self,
|
||||
_: application::ports::ProfileSettingsPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_blocked_domains_page(
|
||||
&self,
|
||||
_: application::ports::BlockedDomainsPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_blocked_actors_page(
|
||||
&self,
|
||||
_: application::ports::BlockedActorsPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_watchlist_page(
|
||||
&self,
|
||||
_: application::ports::WatchlistPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_integrations_page(
|
||||
&self,
|
||||
_: application::ports::IntegrationsPageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
fn render_watch_queue_page(
|
||||
&self,
|
||||
_: application::ports::WatchQueuePageData,
|
||||
) -> Result<String, String> {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
impl crate::ports::RssFeedRenderer for Panic {
|
||||
fn render_feed(&self, _: &[DiaryEntry], _: &str) -> Result<String, String> {
|
||||
panic!()
|
||||
@@ -660,41 +549,44 @@ pub fn make_test_state(auth_service: Arc<dyn AuthService>) -> crate::state::AppS
|
||||
let repo = Arc::new(Panic);
|
||||
crate::state::AppState {
|
||||
app_ctx: AppContext {
|
||||
movie_repository: Arc::clone(&repo) as _,
|
||||
review_repository: Arc::clone(&repo) as _,
|
||||
diary_repository: Arc::clone(&repo) as _,
|
||||
diary_exporter: Arc::clone(&repo) as _,
|
||||
document_parser: Arc::clone(&repo) as _,
|
||||
stats_repository: Arc::clone(&repo) as _,
|
||||
metadata_client: Arc::clone(&repo) as _,
|
||||
poster_fetcher: Arc::clone(&repo) as _,
|
||||
image_storage: Arc::clone(&repo) as _,
|
||||
event_publisher: Arc::clone(&repo) as _,
|
||||
password_hasher: Arc::clone(&repo) as _,
|
||||
user_repository: Arc::clone(&repo) as _,
|
||||
import_session_repository: Arc::clone(&repo) as _,
|
||||
import_profile_repository: Arc::clone(&repo) as _,
|
||||
movie_profile_repository: Arc::clone(&repo) as _,
|
||||
watchlist_repository: Arc::clone(&repo) as _,
|
||||
watch_event_repository: Arc::clone(&repo) as _,
|
||||
webhook_token_repository: Arc::clone(&repo) as _,
|
||||
profile_fields_repository: Arc::clone(&repo) as _,
|
||||
#[cfg(feature = "federation")]
|
||||
remote_watchlist_repository: Arc::clone(&repo) as _,
|
||||
#[cfg(feature = "federation")]
|
||||
social_query: Arc::clone(&repo) as _,
|
||||
person_command: Arc::clone(&repo) as _,
|
||||
person_query: Arc::clone(&repo) as _,
|
||||
search_port: Arc::clone(&repo) as _,
|
||||
search_command: Arc::clone(&repo) as _,
|
||||
auth_service,
|
||||
repos: Repositories {
|
||||
movie: Arc::clone(&repo) as _,
|
||||
review: Arc::clone(&repo) as _,
|
||||
diary: Arc::clone(&repo) as _,
|
||||
stats: Arc::clone(&repo) as _,
|
||||
user: Arc::clone(&repo) as _,
|
||||
import_session: Arc::clone(&repo) as _,
|
||||
import_profile: Arc::clone(&repo) as _,
|
||||
movie_profile: Arc::clone(&repo) as _,
|
||||
watchlist: Arc::clone(&repo) as _,
|
||||
watch_event: Arc::clone(&repo) as _,
|
||||
webhook_token: Arc::clone(&repo) as _,
|
||||
profile_fields: Arc::clone(&repo) as _,
|
||||
person_command: Arc::clone(&repo) as _,
|
||||
person_query: Arc::clone(&repo) as _,
|
||||
search_port: Arc::clone(&repo) as _,
|
||||
search_command: Arc::clone(&repo) as _,
|
||||
#[cfg(feature = "federation")]
|
||||
remote_watchlist: Arc::clone(&repo) as _,
|
||||
#[cfg(feature = "federation")]
|
||||
social_query: Arc::clone(&repo) as _,
|
||||
},
|
||||
services: Services {
|
||||
auth: auth_service,
|
||||
password_hasher: Arc::clone(&repo) as _,
|
||||
metadata: Arc::clone(&repo) as _,
|
||||
poster_fetcher: Arc::clone(&repo) as _,
|
||||
image_storage: Arc::clone(&repo) as _,
|
||||
event_publisher: Arc::clone(&repo) as _,
|
||||
diary_exporter: Arc::clone(&repo) as _,
|
||||
document_parser: Arc::clone(&repo) as _,
|
||||
},
|
||||
config: AppConfig {
|
||||
allow_registration: false,
|
||||
base_url: "http://localhost:3000".to_string(),
|
||||
rate_limit: 20,
|
||||
},
|
||||
},
|
||||
html_renderer: Arc::new(Panic),
|
||||
rss_renderer: Arc::new(Panic),
|
||||
#[cfg(feature = "federation")]
|
||||
ap_service: Arc::new(activitypub::NoopActivityPubService),
|
||||
|
||||
Reference in New Issue
Block a user