use axum::extract::{Json, State}; use super::post; use crate::{test::fixtures, token::app}; #[tokio::test] async fn correct_credentials() { // Set up the environment let app = fixtures::scratch_app().await; let (name, password) = fixtures::login::create_with_password(&app, &fixtures::now()).await; // Call the endpoint let identity = fixtures::cookie::not_logged_in(); let logged_in_at = fixtures::now(); let request = post::Request { name: name.clone(), password, }; let (identity, Json(response)) = post::handler(State(app.clone()), logged_in_at, identity, Json(request)) .await .expect("logged in with valid credentials"); // Verify the return value's basic structure assert_eq!(name, response.name); let secret = identity .secret() .expect("logged in with valid credentials issues an identity cookie"); // Verify the semantics let validated_at = fixtures::now(); let (_, validated_login) = app .tokens() .validate(&secret, &validated_at) .await .expect("identity secret is valid"); assert_eq!(response, validated_login); } #[tokio::test] async fn invalid_name() { // Set up the environment let app = fixtures::scratch_app().await; // Call the endpoint let identity = fixtures::cookie::not_logged_in(); let logged_in_at = fixtures::now(); let (name, password) = fixtures::login::propose(); let request = post::Request { name: name.clone(), password, }; let post::Error(error) = post::handler(State(app.clone()), logged_in_at, identity, Json(request)) .await .expect_err("logged in with an incorrect password fails"); // Verify the return value's basic structure assert!(matches!(error, app::LoginError::Rejected)); } #[tokio::test] async fn incorrect_password() { // Set up the environment let app = fixtures::scratch_app().await; let login = fixtures::login::create(&app, &fixtures::now()).await; // Call the endpoint let logged_in_at = fixtures::now(); let identity = fixtures::cookie::not_logged_in(); let request = post::Request { name: login.name, password: fixtures::login::propose_password(), }; let post::Error(error) = post::handler(State(app.clone()), logged_in_at, identity, Json(request)) .await .expect_err("logged in with an incorrect password"); // Verify the return value's basic structure assert!(matches!(error, app::LoginError::Rejected)); } #[tokio::test] async fn token_expires() { // Set up the environment let app = fixtures::scratch_app().await; let (name, password) = fixtures::login::create_with_password(&app, &fixtures::now()).await; // Call the endpoint let logged_in_at = fixtures::ancient(); let identity = fixtures::cookie::not_logged_in(); let request = post::Request { name, password }; let (identity, _) = post::handler(State(app.clone()), logged_in_at, identity, Json(request)) .await .expect("logged in with valid credentials"); let secret = identity.secret().expect("logged in with valid credentials"); // Verify the semantics let expired_at = fixtures::now(); app.tokens() .expire(&expired_at) .await .expect("expiring tokens never fails"); let verified_at = fixtures::now(); let error = app .tokens() .validate(&secret, &verified_at) .await .expect_err("validating an expired token"); assert!(matches!(error, app::ValidateError::InvalidToken)); }