test: WIP new assignment

This commit is contained in:
Max Hohlfeld 2025-07-01 16:40:40 +02:00
parent 2abeeb20df
commit 512b061c7a
9 changed files with 144 additions and 18 deletions

View File

@ -16,3 +16,4 @@ SMTP_PORT="1025"
# SMTP_LOGIN=""
# SMTP_PASSWORD=""
SMTP_TLSTYPE="none"
RUST_LOG="info,brass_web=trace,brass_db=trace"

View File

@ -1,5 +1,6 @@
use chrono::NaiveDateTime;
use sqlx::PgPool;
use tracing::debug;
use crate::validation::{
AsyncValidate, AsyncValidateError, start_date_time_lies_before_end_date_time,
@ -116,6 +117,11 @@ async fn event_has_free_slot_for_function(
.filter(|a| a.function == *value)
.count();
debug!(
assignments_with_function,
"existing assignments for function"
);
if match *value {
Function::Posten => assignments_with_function >= event.amount_of_posten as usize,
Function::Fuehrungsassistent => {

View File

@ -20,7 +20,7 @@ pub struct User {
}
impl User {
pub async fn create(pool: &PgPool, changeset: UserChangeset) -> Result<i32> {
pub async fn create(pool: &PgPool, changeset: &UserChangeset) -> Result<i32> {
sqlx::query!(
r#"
INSERT INTO user_ (name, email, role, function, areaId)

View File

@ -80,7 +80,7 @@ mod tests {
async fn arrange(pool: &PgPool) -> anyhow::Result<()> {
Location::create(pool, "Location", 1).await?;
User::create(pool, Faker.fake()).await?;
User::create(pool, &Faker.fake()).await?;
let date: NaiveDate = Date().fake();
let start = NaiveTime::from_hms_opt(10, 0, 0).unwrap();

View File

@ -78,13 +78,14 @@ pub async fn post(
mod tests {
use actix_http::StatusCode;
use brass_db::models::{
Area, Availability, AvailabilityChangeset, Event, EventChangeset, Location, Role, User,
UserChangeset,
Area, Assignment, AssignmentChangeset, Availability, AvailabilityChangeset, Event,
EventChangeset, Function, Location, Role, User, UserChangeset,
};
use brass_macros::db_test;
use chrono::NaiveDateTime;
use fake::{Fake, Faker};
use sqlx::PgPool;
use tracing::info;
use crate::utils::test_helper::{
assert_snapshot, test_post, DbTestContext, NaiveDateTimeExt, RequestConfig,
@ -99,7 +100,7 @@ mod tests {
let mut user_changeset: UserChangeset = Faker.fake();
user_changeset.name = String::from("Max Mustermann");
User::create(pool, user_changeset).await.unwrap();
User::create(pool, &user_changeset).await.unwrap();
}
async fn arrange_event(pool: &PgPool, start: NaiveDateTime, end: NaiveDateTime, location: i32) {
@ -228,7 +229,23 @@ mod tests {
#[db_test]
fn fails_assignment_time_doesnt_fit_into_availability_time(context: &DbTestContext) {
assert!(false)
let app = context.app().await;
let start = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 10, 0, 0).unwrap();
let end = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 20, 0, 0).unwrap();
let availability_start = NaiveDateTime::from_ymd_and_hms(2025, 01, 12, 10, 0, 0).unwrap();
let availability_end = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 18, 0, 0).unwrap();
arrange(&context.db_pool).await;
arrange_event(&context.db_pool, start, end, 1).await;
arrange_availability(&context.db_pool, availability_start, availability_end).await;
let config = RequestConfig::new("/assignments/new?availability=1&function=1&event=1")
.with_role(Role::Admin);
let response = test_post::<_, _, String>(&context.db_pool, app, &config, None).await;
assert_eq!(StatusCode::UNPROCESSABLE_ENTITY, response.status());
}
#[db_test]
@ -238,16 +255,111 @@ mod tests {
#[db_test]
fn fails_when_availability_time_already_assigned(context: &DbTestContext) {
assert!(false)
let app = context.app().await;
let start = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 10, 0, 0).unwrap();
let end = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 20, 0, 0).unwrap();
arrange(&context.db_pool).await;
arrange_event(&context.db_pool, start, end, 1).await;
arrange_availability(&context.db_pool, start, end).await;
let assignment_changeset = AssignmentChangeset {
function: Function::Posten,
time: (start, end),
};
Assignment::create(&context.db_pool, 1, 1, assignment_changeset)
.await
.unwrap();
let config = RequestConfig::new("/assignments/new?availability=1&function=1&event=1")
.with_role(Role::Admin);
let response = test_post::<_, _, String>(&context.db_pool, app, &config, None).await;
assert_eq!(StatusCode::UNPROCESSABLE_ENTITY, response.status());
}
#[db_test]
fn fails_when_availability_user_does_not_have_function(context: &DbTestContext) {
assert!(false)
let app = context.app().await;
let start = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 10, 0, 0).unwrap();
let end = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 20, 0, 0).unwrap();
arrange(&context.db_pool).await;
arrange_event(&context.db_pool, start, end, 1).await;
arrange_availability(&context.db_pool, start, end).await;
let config = RequestConfig::new("/assignments/new?availability=1&function=5&event=1")
.with_role(Role::Admin);
let response = test_post::<_, _, String>(&context.db_pool, app, &config, None).await;
assert_eq!(StatusCode::UNPROCESSABLE_ENTITY, response.status());
}
#[db_test]
fn fails_when_event_already_has_enough_assignments_for_function(context: &DbTestContext) {
assert!(false)
let app = context.app().await;
info!("Hallo welt");
let start = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 10, 0, 0).unwrap();
let end = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 20, 0, 0).unwrap();
Location::create(&context.db_pool, &Faker.fake::<String>(), 1)
.await
.unwrap();
let mut user_changeset: UserChangeset = Faker.fake();
user_changeset.functions.push(Function::Fuehrungsassistent);
User::create(&context.db_pool, &user_changeset)
.await
.unwrap();
User::create(&context.db_pool, &user_changeset)
.await
.unwrap();
arrange_event(&context.db_pool, start, end, 1).await;
Availability::create(
&context.db_pool,
1,
AvailabilityChangeset {
time: (start, end),
comment: None,
},
)
.await
.unwrap();
Availability::create(
&context.db_pool,
2,
AvailabilityChangeset {
time: (start, end),
comment: None,
},
)
.await
.unwrap();
let assignment_changeset = AssignmentChangeset {
function: Function::Fuehrungsassistent,
time: (start, end),
};
Assignment::create(&context.db_pool, 1, 1, assignment_changeset)
.await
.unwrap();
let config = RequestConfig::new("/assignments/new?availability=2&function=5&event=1")
.with_role(Role::Admin);
let response = test_post::<_, _, String>(&context.db_pool, app, &config, None).await;
assert_eq!(StatusCode::UNPROCESSABLE_ENTITY, response.status());
}
}

View File

@ -91,7 +91,7 @@ mod tests {
#[db_test]
async fn works_when_user_is_admin(context: &DbTestContext) {
User::create(&context.db_pool, Faker.fake()).await.unwrap();
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
Area::create(&context.db_pool, "Süd").await.unwrap();
@ -157,8 +157,7 @@ mod tests {
#[db_test]
async fn email_gets_cast_to_lowercase(context: &DbTestContext) {
User::create(&context.db_pool, Faker.fake()).await.unwrap();
Area::create(&context.db_pool, "Süd").await.unwrap();
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
let app = context.app().await;
let config = RequestConfig::new("/users/edit/1").with_role(Role::Admin);
@ -189,8 +188,8 @@ mod tests {
#[db_test]
async fn fails_when_email_already_present(context: &DbTestContext) {
User::create(&context.db_pool, Faker.fake()).await.unwrap();
User::create(&context.db_pool, Faker.fake()).await.unwrap();
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
Area::create(&context.db_pool, "Süd").await.unwrap();
let app = context.app().await;

View File

@ -61,7 +61,7 @@ pub async fn post_new(
return Ok(HttpResponse::UnprocessableEntity().body(e.to_string()));
};
let id = User::create(pool.get_ref(), changeset).await?;
let id = User::create(pool.get_ref(), &changeset).await?;
let registration = Registration::insert_new_for_user(pool.get_ref(), id).await?;
let new_user = User::read_by_id(pool.get_ref(), id).await?.unwrap();

View File

@ -92,7 +92,7 @@ mod tests {
#[db_test]
async fn admin_can_lock_and_unlock_user(context: &DbTestContext) {
let app = context.app().await;
User::create(&context.db_pool, Faker.fake()).await.unwrap();
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
let lock_config = RequestConfig {
uri: "/users/1/lock".to_string(),
@ -127,7 +127,7 @@ mod tests {
async fn area_manager_cant_lock_outside_of_his_area(context: &DbTestContext) {
let app = context.app().await;
Area::create(&context.db_pool, "Bereich 2").await.unwrap();
User::create(&context.db_pool, Faker.fake()).await.unwrap();
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
let config = RequestConfig {
uri: "/users/1/lock".to_string(),

View File

@ -7,6 +7,7 @@ use actix_web::{
test::init_service,
};
use rand::{distr::Alphanumeric, rng, Rng};
use tracing_subscriber::{fmt, layer::SubscriberExt, registry, util::SubscriberInitExt, EnvFilter};
use crate::utils::Customization;
use crate::{create_app, mail::Mailer};
@ -32,7 +33,7 @@ impl DbTestContext {
> {
let customization = Customization {
webmaster_email: self.config.webmaster_email.clone(),
hostname: self.config.hostname.clone()
hostname: self.config.hostname.clone(),
};
init_service(create_app(
@ -50,6 +51,13 @@ pub async fn setup() -> DbTestContext {
let init_config: OnceCell<Config> = OnceCell::new();
let config = init_config.get_or_init(|| load_config(&Environment::Test).unwrap());
// TODO: unite with init_tracing in main
let filter = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("info"))
.unwrap();
registry().with(fmt::layer()).with(filter).init();
let test_db_config = prepare_db(&config.database_url).await;
let test_db_pool = PgPoolOptions::new()