summaryrefslogtreecommitdiff
path: root/src/login/routes/test/login.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/login/routes/test/login.rs')
-rw-r--r--src/login/routes/test/login.rs137
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);
+}