diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2025-08-24 16:37:41 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2025-08-26 00:57:57 -0400 |
| commit | c52e24f17ed615b2e2dd55a285eb272014a2ccbf (patch) | |
| tree | 757fbef4a4e8236f831d859370e4774e86138bd5 /src | |
| parent | 6c65e97e49d1d56380aa7d71abb0394b08ff60ca (diff) | |
Factor out common authentication test verification steps into helpers.
These checks tended to be wordy, and were prone to being done subtly differently in different locations for no good reason. Centralizing them cleans this up and makes the tests easier to follow, at the expense of making it somewhat harder to follow what the test is specifically checking.
Diffstat (limited to 'src')
| -rw-r--r-- | src/invite/handlers/accept/test.rs | 24 | ||||
| -rw-r--r-- | src/setup/handlers/setup/test.rs | 30 | ||||
| -rw-r--r-- | src/test/mod.rs | 1 | ||||
| -rw-r--r-- | src/test/verify/identity.rs | 33 | ||||
| -rw-r--r-- | src/test/verify/login.rs | 25 | ||||
| -rw-r--r-- | src/test/verify/mod.rs | 3 | ||||
| -rw-r--r-- | src/test/verify/token.rs | 34 | ||||
| -rw-r--r-- | src/user/handlers/login/test.rs | 29 | ||||
| -rw-r--r-- | src/user/handlers/logout/test.rs | 14 | ||||
| -rw-r--r-- | src/user/handlers/password/test.rs | 44 |
10 files changed, 129 insertions, 108 deletions
diff --git a/src/invite/handlers/accept/test.rs b/src/invite/handlers/accept/test.rs index 5140e3f..4e4a09d 100644 --- a/src/invite/handlers/accept/test.rs +++ b/src/invite/handlers/accept/test.rs @@ -1,6 +1,11 @@ use axum::extract::{Json, Path, State}; -use crate::{empty::Empty, invite::app::AcceptError, name::Name, test::fixtures}; +use crate::{ + empty::Empty, + invite::app::AcceptError, + name::Name, + test::{fixtures, verify}, +}; #[tokio::test] async fn valid_invite() { @@ -34,15 +39,7 @@ async fn valid_invite() { // Verify that the issued token is valid - let secret = identity - .secret() - .expect("newly-issued identity has a token secret"); - let identity = app - .tokens() - .validate(&secret, &fixtures::now()) - .await - .expect("newly-issued identity cookie is valid"); - assert_eq!(name, identity.user.name); + verify::identity::valid_for_name(&app, &identity, &name).await; // Verify that the given credentials can log in @@ -51,12 +48,7 @@ async fn valid_invite() { .login(&name, &password, &fixtures::now()) .await .expect("credentials given on signup are valid"); - let identity = app - .tokens() - .validate(&secret, &fixtures::now()) - .await - .expect("validating a newly-issued token secret succeeds"); - assert_eq!(name, identity.user.name); + verify::token::valid_for_name(&app, &secret, &name).await; } #[tokio::test] diff --git a/src/setup/handlers/setup/test.rs b/src/setup/handlers/setup/test.rs index 133a162..283fe8b 100644 --- a/src/setup/handlers/setup/test.rs +++ b/src/setup/handlers/setup/test.rs @@ -1,6 +1,10 @@ use axum::extract::{Json, State}; -use crate::{empty::Empty, setup::app, test::fixtures}; +use crate::{ + empty::Empty, + setup::app, + test::{fixtures, verify}, +}; #[tokio::test] async fn fresh_instance() { @@ -21,30 +25,10 @@ async fn fresh_instance() { .expect("setup in a fresh app succeeds"); // Verify that the issued token is valid - - let secret = identity - .secret() - .expect("newly-issued identity has a token secret"); - let identity = app - .tokens() - .validate(&secret, &fixtures::now()) - .await - .expect("newly-issued identity cookie is valid"); - assert_eq!(name, identity.user.name); + verify::identity::valid_for_name(&app, &identity, &name).await; // Verify that the given credentials can log in - - let secret = app - .tokens() - .login(&name, &password, &fixtures::now()) - .await - .expect("credentials given on signup are valid"); - let identity = app - .tokens() - .validate(&secret, &fixtures::now()) - .await - .expect("validating a newly-issued token secret succeeds"); - assert_eq!(name, identity.user.name); + verify::login::valid_login(&app, &name, &password).await; } #[tokio::test] diff --git a/src/test/mod.rs b/src/test/mod.rs index d066349..ebbbfef 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -1 +1,2 @@ pub mod fixtures; +pub mod verify; diff --git a/src/test/verify/identity.rs b/src/test/verify/identity.rs new file mode 100644 index 0000000..226ee74 --- /dev/null +++ b/src/test/verify/identity.rs @@ -0,0 +1,33 @@ +use crate::{ + app::App, + name::Name, + test::{fixtures, verify}, + token::{app::ValidateError, extract::IdentityCookie}, + user::User, +}; + +pub async fn valid_for_name(app: &App, identity: &IdentityCookie, name: &Name) { + let secret = identity + .secret() + .expect("identity cookie must be set to be valid"); + verify::token::valid_for_name(app, &secret, name).await; +} + +pub async fn valid_for_user(app: &App, identity: &IdentityCookie, user: &User) { + let secret = identity + .secret() + .expect("identity cookie must be set to be valid"); + verify::token::valid_for_user(app, &secret, user).await; +} + +pub async fn invalid(app: &App, identity: &IdentityCookie) { + let secret = identity + .secret() + .expect("identity cookie must be set to be invalid"); + let validate_err = app + .tokens() + .validate(&secret, &fixtures::now()) + .await + .expect_err("identity cookie secret must be invalid"); + assert!(matches!(validate_err, ValidateError::InvalidToken)); +} diff --git a/src/test/verify/login.rs b/src/test/verify/login.rs new file mode 100644 index 0000000..3f291a3 --- /dev/null +++ b/src/test/verify/login.rs @@ -0,0 +1,25 @@ +use crate::{ + app::App, + name::Name, + password::Password, + test::{fixtures, verify}, + token::app::LoginError, +}; + +pub async fn valid_login(app: &App, name: &Name, password: &Password) { + let secret = app + .tokens() + .login(&name, &password, &fixtures::now()) + .await + .expect("login credentials expected to be valid"); + verify::token::valid_for_name(&app, &secret, &name).await; +} + +pub async fn invalid_login(app: &App, name: &Name, password: &Password) { + let error = app + .tokens() + .login(name, password, &fixtures::now()) + .await + .expect_err("login credentials expected not to be valid"); + assert!(matches!(error, LoginError::Rejected)); +} diff --git a/src/test/verify/mod.rs b/src/test/verify/mod.rs new file mode 100644 index 0000000..f809c90 --- /dev/null +++ b/src/test/verify/mod.rs @@ -0,0 +1,3 @@ +pub mod identity; +pub mod login; +pub mod token; diff --git a/src/test/verify/token.rs b/src/test/verify/token.rs new file mode 100644 index 0000000..99cd31f --- /dev/null +++ b/src/test/verify/token.rs @@ -0,0 +1,34 @@ +use crate::{ + app::App, + name::Name, + test::fixtures, + token::{Secret, app}, + user::User, +}; + +pub async fn valid_for_name(app: &App, secret: &Secret, name: &Name) { + let identity = app + .tokens() + .validate(secret, &fixtures::now()) + .await + .expect("provided secret is valid"); + assert_eq!(name, &identity.user.name); +} + +pub async fn valid_for_user(app: &App, secret: &Secret, user: &User) { + let identity = app + .tokens() + .validate(secret, &fixtures::now()) + .await + .expect("provided secret is valid"); + assert_eq!(user, &identity.user); +} + +pub async fn invalid(app: &App, secret: &Secret) { + let error = app + .tokens() + .validate(secret, &fixtures::now()) + .await + .expect_err("provided secret is invalid"); + assert!(matches!(error, app::ValidateError::InvalidToken)); +} diff --git a/src/user/handlers/login/test.rs b/src/user/handlers/login/test.rs index cb387ad..56fc2c4 100644 --- a/src/user/handlers/login/test.rs +++ b/src/user/handlers/login/test.rs @@ -1,6 +1,10 @@ use axum::extract::{Json, State}; -use crate::{empty::Empty, test::fixtures, token::app}; +use crate::{ + empty::Empty, + test::{fixtures, verify}, + token::app, +}; #[tokio::test] async fn correct_credentials() { @@ -24,19 +28,7 @@ async fn correct_credentials() { // Verify the return value's basic structure - let secret = identity - .secret() - .expect("logged in with valid credentials issues an identity cookie"); - - // Verify the semantics - - let validated = app - .tokens() - .validate(&secret, &fixtures::now()) - .await - .expect("identity secret is valid"); - - assert_eq!(name, validated.user.name); + verify::identity::valid_for_name(&app, &identity, &name).await; } #[tokio::test] @@ -114,12 +106,5 @@ async fn token_expires() { .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)); + verify::token::invalid(&app, &secret).await; } diff --git a/src/user/handlers/logout/test.rs b/src/user/handlers/logout/test.rs index 7151ddf..8ad4853 100644 --- a/src/user/handlers/logout/test.rs +++ b/src/user/handlers/logout/test.rs @@ -1,6 +1,10 @@ use axum::extract::{Json, State}; -use crate::{empty::Empty, test::fixtures, token::app}; +use crate::{ + empty::Empty, + test::{fixtures, verify}, + token::app, +}; #[tokio::test] async fn successful() { @@ -24,16 +28,10 @@ async fn successful() { .expect("logged out with a valid token"); // Verify the return value's basic structure - assert!(response_identity.secret().is_none()); // Verify the semantics - let error = app - .tokens() - .validate(&secret, &now) - .await - .expect_err("secret is invalid"); - assert!(matches!(error, app::ValidateError::InvalidToken)); + verify::token::invalid(&app, &secret).await; } #[tokio::test] diff --git a/src/user/handlers/password/test.rs b/src/user/handlers/password/test.rs index c0f789b..81020a1 100644 --- a/src/user/handlers/password/test.rs +++ b/src/user/handlers/password/test.rs @@ -2,8 +2,7 @@ use axum::extract::{Json, State}; use crate::{ empty::Empty, - test::fixtures, - token::app::{LoginError, ValidateError}, + test::{fixtures, verify}, }; #[tokio::test] @@ -35,47 +34,14 @@ async fn password_change() { assert_ne!(cookie.secret(), new_cookie.secret()); // Verify that we're still ourselves - let new_secret = new_cookie - .secret() - .expect("we should have a secret after changing our password"); - let new_identity = app - .tokens() - .validate(&new_secret, &fixtures::now()) - .await - .expect("the newly-issued secret should be valid"); - assert_eq!(identity.user, new_identity.user); + verify::identity::valid_for_user(&app, &new_cookie, &identity.user).await; // Verify that our original token is no longer valid - let validate_err = app - .tokens() - .validate( - &cookie - .secret() - .expect("original identity cookie has a secret"), - &fixtures::now(), - ) - .await - .expect_err("validating the original identity secret should fail"); - assert!(matches!(validate_err, ValidateError::InvalidToken)); + verify::identity::invalid(&app, &cookie).await; // Verify that our original password is no longer valid - let login_err = app - .tokens() - .login(&name, &password, &fixtures::now()) - .await - .expect_err("logging in with the original password should fail"); - assert!(matches!(login_err, LoginError::Rejected)); + verify::login::invalid_login(&app, &name, &password).await; // Verify that our new password is valid - let secret = app - .tokens() - .login(&name, &to, &fixtures::now()) - .await - .expect("logging in with the new password should succeed"); - let identity = app - .tokens() - .validate(&secret, &fixtures::now()) - .await - .expect("validating a newly-issued token secret succeeds"); - assert_eq!(name, identity.user.name); + verify::login::valid_login(&app, &name, &to).await; } |
