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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
use std::sync::Arc;
use axum::{extract::State, response::IntoResponse, Json};
use axum_extra::routing::TypedPath;
use serde::Deserialize;
use crate::{model::User, state::AppState, Error};
#[derive(Debug, Deserialize, TypedPath)]
#[typed_path("/api/user/:uuid")]
pub struct UserUuid {
pub uuid: uuid::Uuid,
}
impl UserUuid {
/// Get a user with a specific `uuid`
#[tracing::instrument]
pub async fn get(self, State(state): State<Arc<AppState>>) -> impl IntoResponse {
sqlx::query_as!(User, "SELECT * FROM users WHERE uuid = $1", self.uuid)
.fetch_optional(&state.pool)
.await?
.ok_or_else(|| Error::UserNotFound)
.map(Json)
}
}
#[cfg(test)]
mod tests {
use super::*;
use axum::{
body::Body,
http::{Request, StatusCode},
};
use http_body_util::BodyExt;
use sqlx::PgPool;
use tower::ServiceExt;
use crate::init_router;
const JWT_SECRET: &str = "test-jwt-secret-token";
const JWT_MAX_AGE: time::Duration = time::Duration::HOUR;
#[sqlx::test]
async fn test_user_not_found(pool: PgPool) -> Result<(), Error> {
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 user = User {
uuid: uuid::uuid!("4c14f795-86f0-4361-a02f-0edb966fb145"),
name: "Arthur Dent".to_string(),
email: "adent@earth.sol".to_string(),
..Default::default()
};
let request = Request::builder()
.uri(format!("/api/user/{}", user.uuid))
.body(Body::empty())?;
let response = router.oneshot(request).await.unwrap();
assert_eq!(StatusCode::NOT_FOUND, response.status());
Ok(())
}
#[sqlx::test(fixtures(path = "../../fixtures", scripts("users")))]
async fn test_user_ok(pool: PgPool) -> Result<(), Error> {
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 user = User {
uuid: uuid::uuid!("4c14f795-86f0-4361-a02f-0edb966fb145"),
name: "Arthur Dent".to_string(),
email: "adent@earth.sol".to_string(),
..Default::default()
};
let request = Request::builder()
.uri(format!("/api/user/{}", user.uuid))
.body(Body::empty())?;
let response = router.oneshot(request).await.unwrap();
assert_eq!(StatusCode::OK, response.status());
let body_bytes = response.into_body().collect().await?.to_bytes();
let User {
uuid, name, email, ..
} = serde_json::from_slice(&body_bytes)?;
assert_eq!(user.uuid, uuid);
assert_eq!(user.name, name);
assert_eq!(user.email, email);
Ok(())
}
}
|