1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
use std::sync::Arc;
use axum::{
http::{StatusCode, Uri},
middleware::map_request_with_state,
response::IntoResponse,
};
use axum_extra::routing::RouterExt;
use crate::{jwt::authenticate, state::AppState};
mod healthcheck;
mod login;
mod register;
mod user;
#[tracing::instrument]
pub fn init_router(state: Arc<AppState>) -> axum::Router {
axum::Router::new()
.typed_get(user::User::get)
.typed_get(login::Logout::get)
.route_layer(map_request_with_state(state.clone(), authenticate))
.typed_get(healthcheck::HealthCheck::get)
.typed_get(user::UserUuid::get)
.typed_post(register::Register::post)
.typed_post(login::Login::post)
.fallback(fallback)
.with_state(state)
}
pub async fn fallback(uri: Uri) -> impl IntoResponse {
(StatusCode::NOT_FOUND, format!("Route not found: {uri}"))
}
#[cfg(test)]
mod tests {
use super::*;
use axum::{
body::Body,
http::{Request, StatusCode},
};
use sqlx::PgPool;
use tower::ServiceExt;
const JWT_SECRET: &str = "test-jwt-secret-token";
const JWT_MAX_AGE: time::Duration = time::Duration::HOUR;
type TestResult<T = (), E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
#[sqlx::test]
async fn test_route_not_found(pool: PgPool) -> TestResult {
let state = Arc::new(AppState {
pool,
jwt_secret: JWT_SECRET.to_string(),
jwt_max_age: JWT_MAX_AGE,
});
let router = init_router(state.clone());
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(())
}
}
|