Max Mustermann
diff --git a/web/snapshots/brass_web__endpoints__events__get_plan__tests__inner_generates_template_for_admin.snap b/web/snapshots/brass_web__endpoints__events__get_plan__tests__inner_generates_template_for_admin.snap
new file mode 100644
index 00000000..c7dca92f
--- /dev/null
+++ b/web/snapshots/brass_web__endpoints__events__get_plan__tests__inner_generates_template_for_admin.snap
@@ -0,0 +1,210 @@
+---
+source: web/src/endpoints/events/get_plan.rs
+expression: body
+snapshot_kind: text
+---
+
+
+
Eventplanung
+
+
+
Allgemeines
+
+
+
+
+
Name: Große Veranstaltung
+
+
+
+
Datum: Mittwoch, 01.01.2025
+
+
+
+
Uhrzeit: 12:00 Uhr - 01.01.2025 22:00 Uhr
+
+
+
+
Veranstaltungsort: Location
+
+
+
+
+
+
Führungsassistent benötigt: ja
+
+
+
+
+
+
Anzugsordnung: Tuchuniform
+
+
+
+
+
+
+
+
+
Einteilung Personal
+
+
+
+
+
+ Name
+ Funktion
+ Zeitraum
+ Kommentar
+ Planung
+
+
+
+
+
+ Max Mustermann
+
+ Posten
+
+
+ 12:00 bis 01.01.2025 22:00
+
+
+ Kommentar
+
+
+
+
+
+
+ als Posten geplant
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Rudi Tester (Fremdbereich Süd)
+
+ Posten
+
+
+ 12:00 bis 01.01.2025 22:00
+
+
+ Kommentar
+
+
+
+
+
+
+ Planen
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Einteilung Fahrzeuge
+
+
+
+
+
+ 11.49.1 - HLF FF Ost
+
+
+
+
+
+
+
Fahrzeug hinzufügen
+
+
+
+
+
+ 11.19.1 - MTW FF Ost
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/endpoints/assignment/delete.rs b/web/src/endpoints/assignment/delete.rs
index c53433e0..912e45a9 100644
--- a/web/src/endpoints/assignment/delete.rs
+++ b/web/src/endpoints/assignment/delete.rs
@@ -98,7 +98,7 @@ mod tests {
),
comment: None,
};
- Availability::create(pool, 1, new_availability).await?;
+ Availability::create(pool, 1, &new_availability).await?;
let new_assignment = AssignmentChangeset {
function: Function::Posten,
diff --git a/web/src/endpoints/assignment/post_new.rs b/web/src/endpoints/assignment/post_new.rs
index 7c0b0965..711d511b 100644
--- a/web/src/endpoints/assignment/post_new.rs
+++ b/web/src/endpoints/assignment/post_new.rs
@@ -117,7 +117,7 @@ mod tests {
Availability::create(
pool,
1,
- AvailabilityChangeset {
+ &AvailabilityChangeset {
time: (start, end),
comment: None,
},
@@ -335,7 +335,7 @@ mod tests {
Availability::create(
&context.db_pool,
1,
- AvailabilityChangeset {
+ &AvailabilityChangeset {
time: (start, end),
comment: None,
},
@@ -346,7 +346,7 @@ mod tests {
Availability::create(
&context.db_pool,
2,
- AvailabilityChangeset {
+ &AvailabilityChangeset {
time: (start, end),
comment: None,
},
diff --git a/web/src/endpoints/availability/delete.rs b/web/src/endpoints/availability/delete.rs
index 15c18516..c55122b6 100644
--- a/web/src/endpoints/availability/delete.rs
+++ b/web/src/endpoints/availability/delete.rs
@@ -34,21 +34,23 @@ mod tests {
use brass_macros::db_test;
use chrono::NaiveDateTime;
use fake::{Fake, Faker};
+ use sqlx::PgPool;
use crate::utils::test_helper::{
create_test_login_user, test_delete, DbTestContext, NaiveDateTimeExt, RequestConfig,
};
- #[db_test]
- async fn deletes_when_availability_is_from_user_itself(context: &DbTestContext) {
- let app = context.app().await;
- let config = RequestConfig::new("/availability/delete/1");
- create_test_login_user(&context.db_pool, &config).await;
+ async fn arrange(pool: &PgPool, availability_id: i32, area_id: i32) -> Result<(), sqlx::Error> {
+ Area::create(pool, "Süd").await?;
+ let mut changeset: UserChangeset = Faker.fake();
+ changeset.area_id = area_id;
+
+ User::create(pool, &changeset).await?;
Availability::create(
- &context.db_pool,
- 1,
- AvailabilityChangeset {
+ pool,
+ availability_id,
+ &AvailabilityChangeset {
time: (
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
@@ -56,8 +58,18 @@ mod tests {
comment: None,
},
)
- .await
- .unwrap();
+ .await?;
+
+ Ok(())
+ }
+
+ #[db_test]
+ async fn deletes_when_availability_is_from_user_itself(context: &DbTestContext) {
+ let app = context.app().await;
+ let config = RequestConfig::new("/availability/delete/1");
+ create_test_login_user(&context.db_pool, &config).await;
+
+ arrange(&context.db_pool, 1, 1).await.unwrap();
let response = test_delete(&app, &config).await;
assert_eq!(StatusCode::OK, response.status());
@@ -73,22 +85,7 @@ mod tests {
let app = context.app().await;
let config = RequestConfig::new("/availability/delete/1").with_role(Role::AreaManager);
create_test_login_user(&context.db_pool, &config).await;
-
- User::create(&context.db_pool, &Faker.fake()).await.unwrap();
-
- Availability::create(
- &context.db_pool,
- 2,
- AvailabilityChangeset {
- time: (
- NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
- NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
- ),
- comment: None,
- },
- )
- .await
- .unwrap();
+ arrange(&context.db_pool, 2, 1).await.unwrap();
let response = test_delete(&app, &config).await;
assert_eq!(StatusCode::OK, response.status());
@@ -104,26 +101,7 @@ mod tests {
let app = context.app().await;
let config = RequestConfig::new("/availability/delete/1").with_role(Role::AreaManager);
create_test_login_user(&context.db_pool, &config).await;
-
- Area::create(&context.db_pool, "Süd").await.unwrap();
- let mut changeset: UserChangeset = Faker.fake();
- changeset.area_id = 2;
-
- User::create(&context.db_pool, &changeset).await.unwrap();
-
- Availability::create(
- &context.db_pool,
- 2,
- AvailabilityChangeset {
- time: (
- NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
- NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
- ),
- comment: None,
- },
- )
- .await
- .unwrap();
+ arrange(&context.db_pool, 2, 2).await.unwrap();
let response = test_delete(&app, &config).await;
assert_eq!(StatusCode::UNAUTHORIZED, response.status());
@@ -139,22 +117,7 @@ mod tests {
let app = context.app().await;
let config = RequestConfig::new("/availability/delete/1").with_role(Role::Admin);
create_test_login_user(&context.db_pool, &config).await;
-
- User::create(&context.db_pool, &Faker.fake()).await.unwrap();
-
- Availability::create(
- &context.db_pool,
- 2,
- AvailabilityChangeset {
- time: (
- NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
- NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
- ),
- comment: None,
- },
- )
- .await
- .unwrap();
+ arrange(&context.db_pool, 2, 1).await.unwrap();
let response = test_delete(&app, &config).await;
assert_eq!(StatusCode::OK, response.status());
diff --git a/web/src/endpoints/availability/post_new.rs b/web/src/endpoints/availability/post_new.rs
index a346a101..03d5c2aa 100644
--- a/web/src/endpoints/availability/post_new.rs
+++ b/web/src/endpoints/availability/post_new.rs
@@ -66,7 +66,7 @@ pub async fn post(
Availability::update(pool.get_ref(), a.id, changeset).await?;
} else {
- Availability::create(pool.get_ref(), user_for_availability, changeset).await?;
+ Availability::create(pool.get_ref(), user_for_availability, &changeset).await?;
}
let url = utils::get_return_url_for_date(&form.startdate);
diff --git a/web/src/endpoints/availability/put_cross_areal.rs b/web/src/endpoints/availability/put_cross_areal.rs
index 2b61e01e..180119ec 100644
--- a/web/src/endpoints/availability/put_cross_areal.rs
+++ b/web/src/endpoints/availability/put_cross_areal.rs
@@ -106,7 +106,7 @@ mod tests {
Availability::create(
&context.db_pool,
2,
- AvailabilityChangeset {
+ &AvailabilityChangeset {
time: (
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
@@ -169,7 +169,7 @@ mod tests {
Availability::create(
&context.db_pool,
2,
- AvailabilityChangeset {
+ &AvailabilityChangeset {
time: (
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
@@ -216,7 +216,7 @@ mod tests {
Availability::create(
&context.db_pool,
1,
- AvailabilityChangeset {
+ &AvailabilityChangeset {
time: (
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
@@ -267,7 +267,7 @@ mod tests {
Availability::create(
&context.db_pool,
2,
- AvailabilityChangeset {
+ &AvailabilityChangeset {
time: (
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
diff --git a/web/src/endpoints/events/get_plan.rs b/web/src/endpoints/events/get_plan.rs
index ec3c0f3c..098a18d9 100644
--- a/web/src/endpoints/events/get_plan.rs
+++ b/web/src/endpoints/events/get_plan.rs
@@ -18,7 +18,12 @@ use crate::{
use brass_db::models::{Availability, AvailabilityAssignmentState, Event, Role, User, Vehicle};
#[derive(Template)]
-#[template(path = "events/plan.html")]
+#[cfg_attr(not(test), template(path = "events/plan.html"))]
+#[cfg_attr(
+ test,
+ template(path = "events/plan.html", block = "content"),
+ allow(dead_code)
+)]
pub struct PlanEventTemplate {
user: User,
event: Event,
@@ -72,3 +77,132 @@ pub async fn get(
Ok(template.to_response()?)
}
+
+#[cfg(test)]
+mod tests {
+ use actix_http::StatusCode;
+ use brass_macros::db_test;
+ use chrono::NaiveDateTime;
+ use fake::{Fake, Faker};
+ use sqlx::PgPool;
+
+ use crate::utils::test_helper::{
+ assert_snapshot, create_test_login_user, test_get, DbTestContext, NaiveDateTimeExt,
+ RequestConfig, ServiceResponseExt,
+ };
+ use brass_db::models::{
+ Area, Assignment, AssignmentChangeset, Availability, AvailabilityChangeset, Event,
+ EventChangeset, Function, Location, Role, User, UserChangeset, Vehicle, VehicleAssignment,
+ };
+
+ #[db_test]
+ async fn generates_template_for_admin(context: &DbTestContext) {
+ let app = context.app().await;
+ let config = RequestConfig::new("/events/1/plan").with_role(Role::Admin);
+ arrange(&context.db_pool).await.unwrap();
+ create_test_login_user(&context.db_pool, &config).await;
+
+ let (status, body) = test_get(app, &config).await.into_status_and_body().await;
+
+ assert_eq!(StatusCode::OK, status);
+ assert_snapshot!(body);
+ }
+
+ #[db_test]
+ async fn returns_ok_for_area_manager_of_same_area(context: &DbTestContext) {
+ let app = context.app().await;
+ let config = RequestConfig::new("/events/1/plan").with_role(Role::AreaManager);
+ arrange(&context.db_pool).await.unwrap();
+ create_test_login_user(&context.db_pool, &config).await;
+
+ let response = test_get(app, &config).await;
+
+ assert_eq!(StatusCode::OK, response.status());
+ }
+
+ #[db_test]
+ async fn returns_unauthorized_for_area_manager_of_different_area(context: &DbTestContext) {
+ let app = context.app().await;
+ let config = RequestConfig::new("/events/1/plan")
+ .with_role(Role::AreaManager)
+ .with_user_area(2);
+ arrange(&context.db_pool).await.unwrap();
+ create_test_login_user(&context.db_pool, &config).await;
+
+ let response = test_get(app, &config).await;
+
+ assert_eq!(StatusCode::UNAUTHORIZED, response.status());
+ }
+
+ #[db_test]
+ async fn returns_unauthorized_for_user(context: &DbTestContext) {
+ let app = context.app().await;
+ let config = RequestConfig::new("/events/1/plan");
+ arrange(&context.db_pool).await.unwrap();
+ create_test_login_user(&context.db_pool, &config).await;
+
+ let response = test_get(app, &config).await;
+
+ assert_eq!(StatusCode::UNAUTHORIZED, response.status());
+ }
+
+ #[db_test]
+ async fn returns_not_found_when_event_doesnt_exist(context: &DbTestContext) {
+ let app = context.app().await;
+ let config = RequestConfig::new("/events/1/plan").with_role(Role::AreaManager);
+ create_test_login_user(&context.db_pool, &config).await;
+
+ let response = test_get(app, &config).await;
+
+ assert_eq!(StatusCode::NOT_FOUND, response.status());
+ }
+
+ async fn arrange(pool: &PgPool) -> anyhow::Result<()> {
+ Location::create(pool, "Location", 1).await?;
+ Area::create(pool, "Süd").await.unwrap();
+
+ let mut user_changeset: UserChangeset = Faker.fake();
+ user_changeset.name = "Max Mustermann".to_string();
+ User::create(pool, &user_changeset).await?;
+
+ let mut other_area_user: UserChangeset = Faker.fake();
+ other_area_user.area_id = 2;
+ other_area_user.name = "Rudi Tester".to_string();
+ User::create(pool, &other_area_user).await?;
+
+ let start = NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 12, 0, 0).unwrap();
+ let end = NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 22, 0, 0).unwrap();
+
+ let mut new_event = EventChangeset::create_for_test(start, end);
+ new_event.name = "Große Veranstaltung".to_string();
+ Event::create(pool, new_event).await?;
+
+ let new_availability = AvailabilityChangeset {
+ time: (start, end),
+ comment: Some("Kommentar".to_string()),
+ };
+ Availability::create(pool, 1, &new_availability).await?;
+ Availability::create(pool, 2, &new_availability).await?;
+ Availability::update_cross_areal(pool, 2, true)
+ .await
+ .unwrap();
+
+ let new_assignment = AssignmentChangeset {
+ function: Function::Posten,
+ time: (start, end),
+ };
+ Assignment::create(pool, 1, 1, new_assignment).await?;
+
+ Vehicle::create(pool, "11.49.1", "HLF FF Ost")
+ .await
+ .unwrap();
+ Vehicle::create(pool, "11.19.1", "MTW FF Ost")
+ .await
+ .unwrap();
+ VehicleAssignment::create(pool, 1, 1, start, end)
+ .await
+ .unwrap();
+
+ Ok(())
+ }
+}
diff --git a/web/templates/events/plan.html b/web/templates/events/plan.html
index fa34ba56..37d0c890 100644
--- a/web/templates/events/plan.html
+++ b/web/templates/events/plan.html
@@ -32,7 +32,7 @@
-
Führungsassistent benötigt: {% if event.fuehrungsassistent_required %}ja{% else %}nein{% endif %}
+
Führungsassistent benötigt: {% if event.fuehrungsassistent_required %}ja{% else %}nein{% endif -%}
diff --git a/web/templates/events/plan_personal_table.html b/web/templates/events/plan_personal_table.html
index 88edb888..ea7702c9 100644
--- a/web/templates/events/plan_personal_table.html
+++ b/web/templates/events/plan_personal_table.html
@@ -19,10 +19,11 @@