diff --git a/Cargo.toml b/Cargo.toml index 495935c..c3d545d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,4 +28,5 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", default_features = false, features = ["std", "fmt", "ansi"] } [dev-dependencies] -scraper = "0.18" \ No newline at end of file +scraper = "0.18" +percent-encoding = "2.3" diff --git a/src/app/mod.rs b/src/app/mod.rs index 01c45bb..6772b14 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -83,3 +83,80 @@ async fn create_new_user( NewUserTemplate {}, )) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + app::AppState, + authentication::{authenticate_user_with_jwt, ParsedJwt}, + db::fake::FakeDatabase, + }; + use { + axum::{ + body::Body, + http::{header::CONTENT_TYPE, Request, StatusCode}, + routing::RouterIntoService, + }, + percent_encoding::percent_decode_str, + tower::{Service, ServiceExt}, + }; + + fn create_test_app() -> (RouterIntoService, FakeDatabase) { + let db = FakeDatabase::new_empty(); + ( + routes() + .with_state(AppState { db: db.clone() }) + .into_service(), + db, + ) + } + + #[tokio::test] + async fn create_new_user_adds_user_to_database_and_sets_jwt_cookie() { + let (mut app, db) = create_test_app(); + + let request = Request::post("/create_new_user") + .header(CONTENT_TYPE, "application/x-www-form-urlencoded") + .body(Body::from( + "real_name=Joe%20User&email=joe%40user.com&password=abc123", + )) + .unwrap(); + let response = ServiceExt::>::ready(&mut app) + .await + .unwrap() + .call(request) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + let set_cookie = response + .headers() + .get("set-cookie") + .unwrap() + .to_str() + .unwrap(); + let cookie_parts: Vec<_> = set_cookie.split(';').map(|s| s.trim()).collect(); + assert_eq!(2, cookie_parts.len()); + assert_eq!("SameSite=Strict", cookie_parts[1]); + let jwt_parts: Vec<_> = cookie_parts[0].split('=').collect(); + assert_eq!(2, jwt_parts.len()); + assert_eq!("jwt", jwt_parts[0]); + let jwt = percent_decode_str(jwt_parts[1]).decode_utf8().unwrap(); + + match authenticate_user_with_jwt(&db, dbg!(&jwt)).await.unwrap() { + ParsedJwt::Valid(user) => { + assert_eq!("Joe User", user.real_name); + assert_eq!( + "Joe User", + db.get_user_with_id(user.get_id()) + .await + .unwrap() + .unwrap() + .real_name + ); + } + _ => assert!(false), + } + } +}