aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/Cargo.toml5
-rw-r--r--backend/migrations/2021-12-13-145111_users/down.sql1
-rw-r--r--backend/migrations/2021-12-13-145111_users/up.sql4
-rw-r--r--backend/src/lib.rs35
-rw-r--r--backend/src/main.rs34
-rw-r--r--backend/tests/common.rs75
6 files changed, 121 insertions, 33 deletions
diff --git a/backend/Cargo.toml b/backend/Cargo.toml
index b44b5ad..cd70bc0 100644
--- a/backend/Cargo.toml
+++ b/backend/Cargo.toml
@@ -20,4 +20,7 @@ base64 = "0.13.0"
[dependencies.rocket_sync_db_pools]
version = "0.1.0-rc.1"
-features = ["diesel_postgres_pool"] \ No newline at end of file
+features = ["diesel_postgres_pool"]
+
+[dev-dependencies]
+parking_lot = "0.11" \ No newline at end of file
diff --git a/backend/migrations/2021-12-13-145111_users/down.sql b/backend/migrations/2021-12-13-145111_users/down.sql
index 441087a..49285a1 100644
--- a/backend/migrations/2021-12-13-145111_users/down.sql
+++ b/backend/migrations/2021-12-13-145111_users/down.sql
@@ -1 +1,2 @@
+DROP INDEX users_username_index
DROP TABLE users; \ No newline at end of file
diff --git a/backend/migrations/2021-12-13-145111_users/up.sql b/backend/migrations/2021-12-13-145111_users/up.sql
index 6ec7e01..f35e718 100644
--- a/backend/migrations/2021-12-13-145111_users/up.sql
+++ b/backend/migrations/2021-12-13-145111_users/up.sql
@@ -3,4 +3,6 @@ CREATE TABLE users(
username VARCHAR(52) NOT NULL,
password_salt BYTEA NOT NULL,
password_hash BYTEA NOT NULL
-); \ No newline at end of file
+);
+
+CREATE UNIQUE INDEX users_username_index ON users(username); \ No newline at end of file
diff --git a/backend/src/lib.rs b/backend/src/lib.rs
new file mode 100644
index 0000000..0a21850
--- /dev/null
+++ b/backend/src/lib.rs
@@ -0,0 +1,35 @@
+#![feature(proc_macro_hygiene, decl_macro)]
+
+use rocket::{Build, Rocket};
+use rocket_sync_db_pools::database;
+
+#[macro_use]
+extern crate rocket;
+#[macro_use]
+extern crate diesel;
+
+mod db;
+mod routes;
+mod schema;
+
+#[database("postgresql_database")]
+pub struct DbConn(diesel::PgConnection);
+
+#[get("/")]
+fn index() -> &'static str {
+ "Hello, world!"
+}
+
+pub fn rocket() -> Rocket<Build> {
+ rocket::build()
+ .mount(
+ "/",
+ routes![
+ index,
+ routes::users::register,
+ routes::users::login,
+ routes::users::current_user,
+ ],
+ )
+ .attach(DbConn::fairing())
+}
diff --git a/backend/src/main.rs b/backend/src/main.rs
index 6ee54ec..65be48d 100644
--- a/backend/src/main.rs
+++ b/backend/src/main.rs
@@ -1,36 +1,8 @@
-#![feature(proc_macro_hygiene, decl_macro)]
-
-use rocket::{Build, Rocket};
-use rocket_sync_db_pools::database;
-
#[macro_use]
extern crate rocket;
-#[macro_use]
-extern crate diesel;
-
-mod db;
-mod routes;
-mod schema;
-
-#[database("postgresql_database")]
-pub struct DbConn(diesel::PgConnection);
-
-#[get("/")]
-fn index() -> &'static str {
- "Hello, world!"
-}
+extern crate mozaic4_backend;
#[launch]
-fn rocket() -> Rocket<Build> {
- rocket::build()
- .mount(
- "/",
- routes![
- index,
- routes::users::register,
- routes::users::login,
- routes::users::current_user,
- ],
- )
- .attach(DbConn::fairing())
+fn launch() -> _ {
+ mozaic4_backend::rocket()
}
diff --git a/backend/tests/common.rs b/backend/tests/common.rs
index e69de29..8ab68a1 100644
--- a/backend/tests/common.rs
+++ b/backend/tests/common.rs
@@ -0,0 +1,75 @@
+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
+ })
+ }};
+}
+
+#[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(Header::new("Authorization", 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");
+ });
+}