use atproto_identity::key::{KeyType, generate_key}; use sqlx::PgPool; use crate::config::Config; use crate::logging::Logger; use crate::infrastructure::oauth::build_oauth_dependencies; use crate::infrastructure::whisper::WhisperClient; use crate::state::AppState; pub struct TestStateBuilder { config: Config, logger: Logger, db_pool: PgPool, whisper_client: Option, } impl TestStateBuilder { pub fn new() -> Self { let config = test_config(); let logger = Logger::disabled(); let db_pool = PgPool::connect_lazy("postgres://test:test@localhost:5432/test").expect("pool"); Self { config, logger, db_pool, whisper_client: None, } } pub fn with_logger(mut self, logger: Logger) -> Self { self.logger = logger; self } pub fn with_whisper_client(mut self, client: WhisperClient) -> Self { self.whisper_client = Some(client); self } pub fn build(self) -> AppState { let whisper_client = self .whisper_client .unwrap_or_else(|| WhisperClient::new(self.config.clone())); let oauth_dependencies = build_oauth_dependencies(&self.config, self.db_pool.clone()); AppState { config: self.config, whisper_client, logger: self.logger, db_pool: self.db_pool, http_client: oauth_dependencies.http_client, oauth_client_config: oauth_dependencies.oauth_client_config, oauth_request_storage: oauth_dependencies.oauth_request_storage, did_document_storage: oauth_dependencies.did_document_storage, key_resolver: oauth_dependencies.key_resolver, identity_resolver: oauth_dependencies.identity_resolver, oauth_signing_key: oauth_dependencies.oauth_signing_key, } } } pub fn test_config() -> Config { let oauth_signing_key = generate_key(KeyType::P256Private).expect("oauth signing key").to_string(); Config { openai_api_key: "test-key".to_string(), openai_base_url: "http://localhost".to_string(), openai_whisper_model: "whisper-1".to_string(), openai_whisper_response_format: "json".to_string(), bind_addr: "0.0.0.0:3001".to_string(), database_url: "postgres://test:test@localhost:5432/test".to_string(), slipnote_env: "local".to_string(), log_sample_rate: 1.0, transcription_cost_per_second_dollars: 0.000_094_34, axiom_token: None, axiom_dataset: None, axiom_url: None, oauth_client_id: "https://example.com/oauth/client-metadata.json".to_string(), oauth_redirect_uri: "https://example.com/oauth/callback".to_string(), oauth_client_name: None, oauth_client_uri: None, oauth_jwks_uri: None, oauth_signing_key, oauth_scopes: "atproto transition:generic".to_string(), oauth_post_auth_redirect: "/".to_string(), oauth_cookie_name: "slipnote_session".to_string(), oauth_session_ttl_seconds: 60 * 60 * 24 * 7, plc_hostname: "plc.directory".to_string(), oauth_base_url: None, } }