diff --git a/.cargo/config.toml b/.cargo/config.toml index 143a94e9..46e46694 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,5 @@ [alias] db = ["run", "--package", "brass-cli", "--bin", "db", "--"] w = ["watch", "-x", "run", "-i", "web/static/"] -t = ["nextest", "run"] +jt = ["nextest", "run"] +t = ["insta", "test", "--test-runner", "nextest", "--unreferenced", "reject", "--review", "--bins"] diff --git a/web/snapshots/brass_web__endpoints__area__get_edit__tests__inner_produces_template_when_area_exists_and_user_is_admin.snap b/web/snapshots/brass_web__endpoints__area__get_edit__tests__inner_produces_template_when_area_exists_and_user_is_admin.snap new file mode 100644 index 00000000..260f4a31 --- /dev/null +++ b/web/snapshots/brass_web__endpoints__area__get_edit__tests__inner_produces_template_when_area_exists_and_user_is_admin.snap @@ -0,0 +1,56 @@ +--- +source: web/src/endpoints/area/get_edit.rs +expression: body +snapshot_kind: text +--- +
+
+ +
+

Bereich 'Leipzig Ost' bearbeiten

+ + +
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+
+
diff --git a/web/snapshots/brass_web__endpoints__area__get_new__inner_produces_template.snap b/web/snapshots/brass_web__endpoints__area__get_new__tests__inner_produces_template_when_user_is_admin.snap similarity index 100% rename from web/snapshots/brass_web__endpoints__area__get_new__inner_produces_template.snap rename to web/snapshots/brass_web__endpoints__area__get_new__tests__inner_produces_template_when_user_is_admin.snap diff --git a/web/src/endpoints/area/delete.rs b/web/src/endpoints/area/delete.rs index 51abfd4d..3b04952e 100644 --- a/web/src/endpoints/area/delete.rs +++ b/web/src/endpoints/area/delete.rs @@ -1,5 +1,4 @@ use actix_web::{web, HttpResponse, Responder}; -use brass_macros::db_test; use sqlx::PgPool; use crate::{ @@ -8,9 +7,6 @@ use crate::{ utils::ApplicationError, }; -#[cfg(test)] -use crate::utils::test_helper::{test_delete, DbTestContext, RequestConfig, StatusCode}; - #[actix_web::delete("/area/delete/{id}")] pub async fn delete( user: web::ReqData, @@ -30,48 +26,90 @@ pub async fn delete( Ok(HttpResponse::Ok().finish()) } -#[db_test] -async fn works_when_user_is_admin(context: &DbTestContext) { - Area::create(&context.db_pool, "Area to delete") - .await - .unwrap(); - assert!(Area::read_by_id(&context.db_pool, 2) - .await - .unwrap() - .is_some()); - - let app = context.app().await; - let config = RequestConfig { - uri: "/area/delete/2".to_string(), - role: Role::Admin, - function: crate::models::Function::Posten, - user_area: 1, +#[cfg(test)] +mod tests { + use crate::{ + models::{Area, Function, Location, Role}, + utils::test_helper::{test_delete, DbTestContext, RequestConfig, StatusCode}, }; - let response = test_delete(&context.db_pool, app, &config).await; + use brass_macros::db_test; - assert_eq!(StatusCode::OK, response.status()); - assert!(Area::read_by_id(&context.db_pool, 2) - .await - .unwrap() - .is_none()); -} - -#[db_test] -async fn does_not_work_when_user_is_not_admin(context: &DbTestContext) { - Area::create(&context.db_pool, "Area to delete") - .await - .unwrap(); - assert!(Area::read_by_id(&context.db_pool, 2) - .await - .unwrap() - .is_some()); - - let app = context.app().await; - let response = test_delete(&context.db_pool, app, &RequestConfig::new("/area/delete/2")).await; - - assert_eq!(StatusCode::UNAUTHORIZED, response.status()); - assert!(Area::read_by_id(&context.db_pool, 2) - .await - .unwrap() - .is_some()); + #[db_test] + async fn deletes_area_when_user_is_admin_and_area_exists(context: &DbTestContext) { + Area::create(&context.db_pool, "Area to delete") + .await + .unwrap(); + assert!(Area::read_by_id(&context.db_pool, 2) + .await + .unwrap() + .is_some()); + + let app = context.app().await; + let config = RequestConfig { + uri: "/area/delete/2".to_string(), + role: Role::Admin, + function: Function::Posten, + user_area: 1, + }; + let response = test_delete(&context.db_pool, app, &config).await; + + assert_eq!(StatusCode::OK, response.status()); + assert!(Area::read_by_id(&context.db_pool, 2) + .await + .unwrap() + .is_none()); + } + + #[db_test] + async fn returns_unauthorized_when_user_is_not_admin(context: &DbTestContext) { + let app = context.app().await; + let response = + test_delete(&context.db_pool, app, &RequestConfig::new("/area/delete/1")).await; + + assert_eq!(StatusCode::UNAUTHORIZED, response.status()); + } + + #[db_test] + async fn returns_not_found_when_area_does_not_exist(context: &DbTestContext) { + let app = context.app().await; + let config = RequestConfig { + uri: "/area/delete/2".to_string(), + role: Role::Admin, + function: Function::Posten, + user_area: 1, + }; + let response = test_delete(&context.db_pool, app, &config).await; + + assert_eq!(StatusCode::NOT_FOUND, response.status()); + } + + #[db_test] + async fn deletes_location_connected_to_area(context: &DbTestContext) { + Area::create(&context.db_pool, "Area to delete") + .await + .unwrap(); + + Location::create(&context.db_pool, "Location connected to area", 2) + .await + .unwrap(); + + let app = context.app().await; + let config = RequestConfig { + uri: "/area/delete/2".to_string(), + role: Role::Admin, + function: Function::Posten, + user_area: 1, + }; + let response = test_delete(&context.db_pool, app, &config).await; + + assert_eq!(StatusCode::OK, response.status()); + assert!(Area::read_by_id(&context.db_pool, 2) + .await + .unwrap() + .is_none()); + assert!(Location::read_by_id(&context.db_pool, 1) + .await + .unwrap() + .is_none()); + } } diff --git a/web/src/endpoints/area/get_edit.rs b/web/src/endpoints/area/get_edit.rs index 55e1b685..fa0bc7d2 100644 --- a/web/src/endpoints/area/get_edit.rs +++ b/web/src/endpoints/area/get_edit.rs @@ -28,3 +28,62 @@ async fn get( Ok(HttpResponse::NotFound().finish()) } } + +#[cfg(test)] +mod tests { + use actix_http::StatusCode; + use brass_macros::db_test; + + use crate::{ + models::{Function, Role}, + utils::test_helper::{assert_snapshot, read_body, test_get, DbTestContext, RequestConfig}, + }; + + #[db_test] + async fn produces_template_when_area_exists_and_user_is_admin(context: &DbTestContext) { + let app = context.app().await; + + let config = RequestConfig { + uri: "/area/edit/1".to_string(), + role: Role::Admin, + function: Function::Posten, + user_area: 1, + }; + let response = test_get(&context.db_pool, app, &config).await; + + assert_eq!(StatusCode::OK, response.status()); + + let body = read_body(response).await; + assert_snapshot!(body); + } + + #[db_test] + async fn returns_unauthorized_when_user_is_not_admin(context: &DbTestContext) { + let app = context.app().await; + + let config = RequestConfig { + uri: "/area/edit/1".to_string(), + role: Role::AreaManager, + function: Function::Posten, + user_area: 1, + }; + let response = test_get(&context.db_pool, app, &config).await; + + assert_eq!(StatusCode::UNAUTHORIZED, response.status()); + } + + #[db_test] + async fn returns_not_found_when_area_does_not_exist(context: &DbTestContext) { + let app = context.app().await; + + let config = RequestConfig { + uri: "/area/edit/2".to_string(), + role: Role::Admin, + function: Function::Posten, + user_area: 1, + }; + let response = test_get(&context.db_pool, app, &config).await; + + assert_eq!(StatusCode::NOT_FOUND, response.status()); + } +} diff --git a/web/src/endpoints/area/get_new.rs b/web/src/endpoints/area/get_new.rs index e52dae39..1d6d7670 100644 --- a/web/src/endpoints/area/get_new.rs +++ b/web/src/endpoints/area/get_new.rs @@ -4,12 +4,6 @@ use crate::{ utils::{ApplicationError, TemplateResponse}, }; use actix_web::{web, Responder}; -use brass_macros::db_test; - -#[cfg(test)] -use crate::utils::test_helper::{ - assert_snapshot, read_body, test_get, DbTestContext, RequestConfig, StatusCode, -}; #[actix_web::get("/area/new")] async fn get(user: web::ReqData) -> Result { @@ -25,19 +19,45 @@ async fn get(user: web::ReqData) -> Result, pool: web::Data, form: web::Form, -) -> impl Responder { +) -> Result { if user.role != Role::Admin { - return HttpResponse::Unauthorized().finish(); + return Err(ApplicationError::Unauthorized); } - match Area::create(pool.get_ref(), &form.name).await { - Ok(_) => { - HttpResponse::Found() - .insert_header((LOCATION, "/locations")) - .insert_header(("HX-LOCATION", "/locations")) - .finish() - } - Err(err) => { - println!("{}", err); - HttpResponse::InternalServerError().finish() - } + Area::create(pool.get_ref(), &form.name).await?; + + Ok(HttpResponse::Found() + .insert_header((LOCATION, "/locations")) + .insert_header(("HX-LOCATION", "/locations")) + .finish()) +} + +#[cfg(test)] +mod tests { + use actix_http::StatusCode; + use brass_macros::db_test; + + use crate::{ + endpoints::area::AreaForm, + models::{Area, Function, Role}, + utils::test_helper::{test_post, DbTestContext, RequestConfig}, + }; + + #[db_test] + async fn updates_area_when_user_is_admin_and_area_exists(context: &DbTestContext) { + let app = context.app().await; + + let config = RequestConfig { + uri: "/area/new".to_string(), + role: Role::Admin, + function: Function::Posten, + user_area: 1, + }; + + let request = AreaForm { + name: "Neuer Name".to_string(), + }; + + let response = test_post(&context.db_pool, app, &config, request).await; + + assert_eq!(StatusCode::FOUND, response.status()); + + let updated_area = Area::read_by_id(&context.db_pool, 2) + .await + .unwrap() + .unwrap(); + + assert_eq!("Neuer Name".to_string(), updated_area.name); + } + + #[db_test] + async fn returns_unauthorized_when_user_is_not_admin(context: &DbTestContext) { + let app = context.app().await; + + let config = RequestConfig { + uri: "/area/new".to_string(), + role: Role::AreaManager, + function: Function::Posten, + user_area: 1, + }; + + let request = AreaForm { + name: "Neuer Name".to_string(), + }; + + let response = test_post(&context.db_pool, app, &config, request).await; + + assert_eq!(StatusCode::UNAUTHORIZED, response.status()); } }