use axum::{http::Uri, response::IntoResponse}; use tower_http::{cors::CorsLayer, trace::TraceLayer}; pub use error::{Error, Result}; pub mod api; pub mod auth; pub mod error; pub mod state; pub mod utils; pub fn router() -> axum::Router { axum::Router::new() .nest("/api", api::router()) .merge(auth::router()) .fallback(fallback) // TODO: do this correctly! .layer(CorsLayer::permissive()) .layer(TraceLayer::new_for_http()) } pub async fn fallback(uri: Uri) -> impl IntoResponse { Error::RouteNotFound(uri) } #[cfg(test)] pub(crate) mod tests { use crate::state::AppState; use super::*; use std::sync::Once; use axum::{ body::Body, http::{Request, StatusCode}, Router, }; use sqlx::PgPool; use tower::ServiceExt; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; pub type TestResult> = std::result::Result; pub const JWT_SECRET: &str = "test-jwt-secret-token"; static INIT: Once = Once::new(); pub fn setup_test_env() { INIT.call_once(|| { tracing_subscriber::registry() .with(tracing_subscriber::EnvFilter::from_default_env()) .with(tracing_subscriber::fmt::layer().with_test_writer()) .init(); std::env::set_var("JWT_SECRET", JWT_SECRET); }); } #[sqlx::test] async fn test_fallback_not_found(pool: PgPool) -> TestResult { setup_test_env(); let router = Router::new().merge(router()).with_state(AppState { pool }); let request = Request::builder() .uri("/does-not-exist") .body(Body::empty())?; let response = router.oneshot(request).await?; assert_eq!(StatusCode::NOT_FOUND, response.status()); Ok(()) } }