use rocket::{ form::Form, get, post, put, response::{Flash, Redirect}, routes, FromForm, Route, State, }; use serde::Serialize; use sqlx::SqlitePool; use crate::model::{ planned_event::PlannedEvent, tripdetails::{TripDetails, TripDetailsToAdd}, user::AdminUser, }; //TODO: add constraints (e.g. planned_amount_cox > 0) #[derive(FromForm, Serialize)] struct AddPlannedEventForm<'r> { name: &'r str, planned_amount_cox: i32, tripdetails: TripDetailsToAdd<'r>, } #[post("/planned-event", data = "")] async fn create( db: &State, data: Form>, _admin: AdminUser, ) -> Flash { let data = data.into_inner(); let trip_details_id = TripDetails::create(db, data.tripdetails).await; let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc. we //just created //the object PlannedEvent::create(db, data.name, data.planned_amount_cox, trip_details).await; Flash::success(Redirect::to("/"), "Successfully planned the event") } //TODO: add constraints (e.g. planned_amount_cox > 0) #[derive(FromForm)] struct UpdatePlannedEventForm<'r> { id: i64, planned_amount_cox: i32, max_people: i32, notes: Option<&'r str>, always_show: bool, } #[put("/planned-event", data = "")] async fn update( db: &State, data: Form>, _admin: AdminUser, ) -> Flash { match PlannedEvent::find_by_id(db, data.id).await { Some(planned_event) => { planned_event .update( db, data.planned_amount_cox, data.max_people, data.notes, data.always_show, ) .await; Flash::success(Redirect::to("/"), "Successfully edited the event") } None => Flash::error(Redirect::to("/"), "Planned event id not found"), } } #[get("/planned-event//delete")] async fn delete(db: &State, id: i64, _admin: AdminUser) -> Flash { match PlannedEvent::find_by_id(db, id).await { Some(planned_event) => { planned_event.delete(db).await; Flash::success(Redirect::to("/"), "Successfully deleted the event") } None => Flash::error(Redirect::to("/"), "PlannedEvent does not exist"), } } pub fn routes() -> Vec { routes![create, delete, update] } #[cfg(test)] mod test { use rocket::{ http::{ContentType, Status}, local::asynchronous::Client, }; use sqlx::SqlitePool; use super::*; use crate::testdb; #[sqlx::test] fn test_delete() { let db = testdb!(); let _ = PlannedEvent::find_by_id(&db, 1).await.unwrap(); let rocket = rocket::build().manage(db.clone()); let rocket = crate::tera::config(rocket); let client = Client::tracked(rocket).await.unwrap(); let login = client .post("/auth") .header(ContentType::Form) // Set the content type to form .body("name=admin&password=admin"); // Add the form data to the request body; login.dispatch().await; let req = client.get("/admin/planned-event/1/delete"); let response = req.dispatch().await; assert_eq!(response.status(), Status::SeeOther); assert_eq!(response.headers().get("Location").next(), Some("/")); let flash_cookie = response .cookies() .get("_flash") .expect("Expected flash cookie"); assert_eq!( flash_cookie.value(), "7:successSuccessfully deleted the event" ); let event = PlannedEvent::find_by_id(&db, 1).await; assert_eq!(event, None); } #[sqlx::test] fn test_delete_invalid_id() { let db = testdb!(); let rocket = rocket::build().manage(db.clone()); let rocket = crate::tera::config(rocket); let client = Client::tracked(rocket).await.unwrap(); let login = client .post("/auth") .header(ContentType::Form) // Set the content type to form .body("name=admin&password=admin"); // Add the form data to the request body; login.dispatch().await; let req = client.get("/admin/planned-event/1337/delete"); let response = req.dispatch().await; assert_eq!(response.status(), Status::SeeOther); assert_eq!(response.headers().get("Location").next(), Some("/")); let flash_cookie = response .cookies() .get("_flash") .expect("Expected flash cookie"); assert_eq!(flash_cookie.value(), "5:errorPlannedEvent does not exist"); let _ = PlannedEvent::find_by_id(&db, 1).await.unwrap(); } }