aboutsummaryrefslogtreecommitdiff
path: root/backend/tests/login.rs
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2021-12-15 22:40:55 +0100
committerIlion Beyst <ilion.beyst@gmail.com>2021-12-15 22:40:55 +0100
commit6aa72b3c8717f32e62c772aeed327d3cd9a6fa65 (patch)
treee6ac67e68c410aed1f0baa2857aeaf60d73448bd /backend/tests/login.rs
parent13cdbc7ff760ae91ee3f62b2a2f62c7559ccaa3c (diff)
downloadplanetwars.dev-6aa72b3c8717f32e62c772aeed327d3cd9a6fa65.tar.xz
planetwars.dev-6aa72b3c8717f32e62c772aeed327d3cd9a6fa65.zip
gracefully handle invalid login credentials
Diffstat (limited to 'backend/tests/login.rs')
-rw-r--r--backend/tests/login.rs106
1 files changed, 106 insertions, 0 deletions
diff --git a/backend/tests/login.rs b/backend/tests/login.rs
new file mode 100644
index 0000000..9c70af2
--- /dev/null
+++ b/backend/tests/login.rs
@@ -0,0 +1,106 @@
+extern crate mozaic4_backend;
+
+use diesel;
+use diesel::prelude::*;
+use mozaic4_backend::DbConn;
+use rocket::http::{ContentType, Header, Status};
+use rocket::local::asynchronous::Client;
+
+// We use a lock to synchronize between tests so DB operations don't collide.
+// For now. In the future, we'll have a nice way to run each test in a DB
+// transaction so we can regain concurrency.
+static DB_LOCK: parking_lot::Mutex<()> = parking_lot::const_mutex(());
+
+async fn reset_db(db: &DbConn) {
+ db.run(|conn| {
+ diesel::sql_query("TRUNCATE TABLE users, sessions")
+ .execute(conn)
+ .expect("drop all tables");
+ })
+ .await
+}
+
+macro_rules! run_test {
+ (|$client:ident, $conn:ident| $block:expr) => {{
+ let _lock = DB_LOCK.lock();
+
+ rocket::async_test(async move {
+ let $client = Client::tracked(mozaic4_backend::rocket())
+ .await
+ .expect("Rocket client");
+ let db = mozaic4_backend::DbConn::get_one($client.rocket()).await;
+ let $conn = db.expect("failed to get database connection for testing");
+ reset_db(&$conn).await;
+
+ $block
+ })
+ }};
+}
+
+pub struct BearerAuth {
+ token: String,
+}
+
+impl BearerAuth {
+ pub fn new(token: String) -> Self {
+ Self { token }
+ }
+}
+
+impl<'a> Into<Header<'a>> for BearerAuth {
+ fn into(self) -> Header<'a> {
+ Header::new("Authorization", format!("Bearer {}", self.token))
+ }
+}
+
+#[test]
+fn test_registration() {
+ run_test!(|client, _conn| {
+ let response = client
+ .post("/register")
+ .header(ContentType::JSON)
+ .body(r#"{"username": "piepkonijn", "password": "geheim123"}"#)
+ .dispatch()
+ .await;
+
+ assert_eq!(response.status(), Status::Ok);
+ assert_eq!(response.content_type(), Some(ContentType::JSON));
+
+ let response = client
+ .post("/login")
+ .header(ContentType::JSON)
+ .body(r#"{"username": "piepkonijn", "password": "geheim123"}"#)
+ .dispatch()
+ .await;
+
+ assert_eq!(response.status(), Status::Ok);
+ let token = response.into_string().await.unwrap();
+
+ let response = client
+ .get("/users/me")
+ .header(BearerAuth::new(token))
+ .dispatch()
+ .await;
+
+ assert_eq!(response.status(), Status::Ok);
+ assert_eq!(response.content_type(), Some(ContentType::JSON));
+ let resp = response.into_string().await.unwrap();
+ let json: serde_json::Value = serde_json::from_str(&resp).unwrap();
+ assert_eq!(json["username"], "piepkonijn");
+ });
+}
+
+#[test]
+fn test_reject_invalid_credentials() {
+ run_test!(|client, _conn| {
+ let response = client
+ .post("/login")
+ .header(ContentType::JSON)
+ .body(r#"{"username": "piepkonijn", "password": "letmeinplease"}"#)
+ .dispatch()
+ .await;
+
+ assert_eq!(response.status(), Status::Forbidden);
+ // assert_eq!(response.content_type(), Some(ContentType::JSON));
+ });
+}