diff options
Diffstat (limited to 'src/login/routes/test/login.rs')
| -rw-r--r-- | src/login/routes/test/login.rs | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/login/routes/test/login.rs b/src/login/routes/test/login.rs new file mode 100644 index 0000000..4fa491a --- /dev/null +++ b/src/login/routes/test/login.rs @@ -0,0 +1,137 @@ +use axum::{ + extract::{Json, State}, + http::StatusCode, +}; + +use crate::{ + login::{app, routes}, + test::fixtures, +}; + +#[tokio::test] +async fn new_identity() { + // Set up the environment + + let app = fixtures::scratch_app().await; + + // Call the endpoint + + let identity = fixtures::identity::not_logged_in(); + let logged_in_at = fixtures::now(); + let (name, password) = fixtures::login::propose(); + let request = routes::LoginRequest { + name: name.clone(), + password, + }; + let (identity, status) = + routes::on_login(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!(StatusCode::NO_CONTENT, status); + let secret = identity.secret().expect("logged in with valid credentials"); + + // Verify the semantics + + let validated_at = fixtures::now(); + let validated = app + .logins() + .validate(secret, &validated_at) + .await + .expect("identity secret is valid"); + + assert_eq!(name, validated.name); +} + +#[tokio::test] +async fn existing_identity() { + // Set up the environment + + let app = fixtures::scratch_app().await; + let (name, password) = fixtures::login::create_for_login(&app).await; + + // Call the endpoint + + let identity = fixtures::identity::not_logged_in(); + let logged_in_at = fixtures::now(); + let request = routes::LoginRequest { + name: name.clone(), + password, + }; + let (identity, status) = + routes::on_login(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!(StatusCode::NO_CONTENT, status); + let secret = identity.secret().expect("logged in with valid credentials"); + + // Verify the semantics + + let validated_at = fixtures::now(); + let validated_login = app + .logins() + .validate(secret, &validated_at) + .await + .expect("identity secret is valid"); + + assert_eq!(name, validated_login.name); +} + +#[tokio::test] +async fn authentication_failed() { + // Set up the environment + + let app = fixtures::scratch_app().await; + let login = fixtures::login::create(&app).await; + + // Call the endpoint + + let logged_in_at = fixtures::now(); + let identity = fixtures::identity::not_logged_in(); + let request = routes::LoginRequest { + name: login.name, + password: fixtures::login::propose_password(), + }; + let routes::LoginError(error) = + routes::on_login(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 + + fixtures::error::expected!(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_for_login(&app).await; + + // Call the endpoint + + let logged_in_at = fixtures::ancient(); + let identity = fixtures::identity::not_logged_in(); + let request = routes::LoginRequest { name, password }; + let (identity, _) = routes::on_login(State(app.clone()), logged_in_at, identity, Json(request)) + .await + .expect("logged in with valid credentials"); + let token = identity.secret().expect("logged in with valid credentials"); + + // Verify the semantics + + let verified_at = fixtures::now(); + let error = app + .logins() + .validate(token, &verified_at) + .await + .expect_err("validating an expired token"); + + fixtures::error::expected!(error, app::ValidateError::InvalidToken); +} |
