//! Helpers to build a fully wired app on an in-memory database for integration tests. use std::sync::{Arc, Mutex}; use application::{JobHandler, JobLog, JobRunner}; use async_trait::async_trait; use axum::Router; use domain::ports::Mailer; use domain::settings::SmtpSettings; use domain::DomainError; use crate::{build_app, AppState, Config}; pub fn test_config() -> Config { Config { database_url: "sqlite::memory:".into(), jwt_secret: "test-secret-test-secret-test-secret-1234".into(), master_key: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f".into(), fake_host: true, kubeconfig: None, bind: "127.0.0.1:0".parse().unwrap(), bootstrap_admin: None, cookie_secure: false, frontend_dir: "/nonexistent".into(), } } /// Mails "sent" by all test apps of this process. static SENT: Mutex, String, String)>> = Mutex::new(Vec::new()); pub struct RecordingMailer; #[async_trait] impl Mailer for RecordingMailer { async fn send( &self, _: &SmtpSettings, to: &[String], subject: &str, body: &str, ) -> Result<(), DomainError> { SENT.lock() .unwrap() .push((to.to_vec(), subject.into(), body.into())); Ok(()) } } pub fn sent_mails(_app: &Router) -> Vec<(Vec, String, String)> { SENT.lock().unwrap().clone() } /// Test handler for kinds without a real implementation yet. pub struct TestJob; #[async_trait] impl JobHandler for TestJob { async fn run(&self, _params: Option, log: &dyn JobLog) -> Result<(), String> { log.line("test handler ran").await; Ok(()) } } pub fn register_test_jobs(runner: JobRunner) -> JobRunner { runner } pub async fn build_test_app() -> Router { build_test_app_with(test_config()).await } pub async fn build_test_app_with_admin(email: &str, password: &str) -> Router { let cfg = Config { bootstrap_admin: Some((email.into(), password.into())), ..test_config() }; build_test_app_with(cfg).await } async fn build_test_app_with(cfg: Config) -> Router { let pool = infrastructure::connect(&cfg.database_url) .await .expect("db"); let state = AppState::with_adapters( cfg, pool, Arc::new(RecordingMailer), Arc::new(infrastructure::FakeHostInspector), Arc::new(infrastructure::FakeHostUpdater), Arc::new(infrastructure::FakeClusterGateway), register_test_jobs, ) .expect("state"); state.bootstrap().await.expect("bootstrap"); build_app(state) }