rowt/src/tera/admin/boat.rs
Philipp Hofer 3406b66f41
Some checks failed
CI/CD Pipeline / deploy-staging (push) Has been cancelled
CI/CD Pipeline / deploy-main (push) Has been cancelled
CI/CD Pipeline / test (push) Has been cancelled
allow vorstand to edit boats
2025-02-11 09:22:22 +01:00

320 lines
9.7 KiB
Rust

use crate::model::{
boat::{Boat, BoatToAdd, BoatToUpdate},
location::Location,
log::Log,
user::{User, UserWithDetails, VorstandUser},
};
use rocket::{
form::Form,
get, post,
request::FlashMessage,
response::{Flash, Redirect},
routes, Route, State,
};
use rocket_dyn_templates::{tera::Context, Template};
use sqlx::SqlitePool;
#[get("/boat")]
async fn index(
db: &State<SqlitePool>,
admin: VorstandUser,
flash: Option<FlashMessage<'_>>,
) -> Template {
let boats = Boat::all(db).await;
let locations = Location::all(db).await;
let users = User::all(db).await;
let mut context = Context::new();
if let Some(msg) = flash {
context.insert("flash", &msg.into_inner());
}
context.insert("boats", &boats);
context.insert("locations", &locations);
context.insert("users", &users);
context.insert(
"loggedin_user",
&UserWithDetails::from_user(admin.user, db).await,
);
Template::render("admin/boat/index", context.into_json())
}
#[get("/boat/<boat>/delete")]
async fn delete(db: &State<SqlitePool>, admin: VorstandUser, boat: i32) -> Flash<Redirect> {
let boat = Boat::find_by_id(db, boat).await;
Log::create(db, format!("{} deleted boat: {boat:?}", admin.user.name)).await;
match boat {
Some(boat) => {
boat.delete(db).await;
Flash::success(
Redirect::to("/admin/boat"),
format!("Boot {} gelöscht", boat.name),
)
}
None => Flash::error(Redirect::to("/admin/boat"), "Boat does not exist"),
}
}
#[post("/boat/<boat_id>", data = "<data>")]
async fn update(
db: &State<SqlitePool>,
data: Form<BoatToUpdate<'_>>,
boat_id: i32,
_admin: VorstandUser,
) -> Flash<Redirect> {
let boat = Boat::find_by_id(db, boat_id).await;
let Some(boat) = boat else {
return Flash::error(Redirect::to("/admin/boat"), "Boat does not exist!");
};
match boat.update(db, data.into_inner()).await {
Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot bearbeitet"),
Err(e) => Flash::error(Redirect::to("/admin/boat"), e),
}
}
#[post("/boat/new", data = "<data>")]
async fn create(
db: &State<SqlitePool>,
data: Form<BoatToAdd<'_>>,
_admin: VorstandUser,
) -> Flash<Redirect> {
match Boat::create(db, data.into_inner()).await {
Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot hinzugefügt"),
Err(e) => Flash::error(Redirect::to("/admin/boat"), e),
}
}
pub fn routes() -> Vec<Route> {
routes![index, create, delete, update]
}
#[cfg(test)]
mod test {
use rocket::{
http::{ContentType, Status},
local::asynchronous::Client,
};
use sqlx::SqlitePool;
use crate::tera::admin::boat::Boat;
use crate::testdb;
#[sqlx::test]
fn test_boat_index() {
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/boat");
let response = req.dispatch().await;
assert_eq!(response.status(), Status::Ok);
let text = response.into_string().await.unwrap();
assert!(&text.contains("Neues Boot"));
assert!(&text.contains("Kaputtes Boot :-("));
assert!(&text.contains("Haichenbach"));
}
#[sqlx::test]
fn test_succ_update() {
let db = testdb!();
let boat = Boat::find_by_id(&db, 1).await.unwrap();
assert_eq!(boat.name, "Haichenbach");
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
.post("/admin/boat/1")
.header(ContentType::Form)
.body("name=Haichiii&amount_seats=1&location_id=1");
let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther);
assert_eq!(
response.headers().get("Location").next(),
Some("/admin/boat")
);
let flash_cookie = response
.cookies()
.get("_flash")
.expect("Expected flash cookie");
assert_eq!(flash_cookie.value(), "7:successBoot bearbeitet");
let boat = Boat::find_by_id(&db, 1).await.unwrap();
assert_eq!(boat.name, "Haichiii");
}
#[sqlx::test]
fn test_update_wrong_boat() {
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
.post("/admin/boat/1337")
.header(ContentType::Form)
.body("name=Haichiii&amount_seats=1&location_id=1");
let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther);
assert_eq!(
response.headers().get("Location").next(),
Some("/admin/boat")
);
let flash_cookie = response
.cookies()
.get("_flash")
.expect("Expected flash cookie");
assert_eq!(flash_cookie.value(), "5:errorBoat does not exist!");
let boat = Boat::find_by_id(&db, 1).await.unwrap();
assert_eq!(boat.name, "Haichenbach");
}
#[sqlx::test]
fn test_update_wrong_foreign() {
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
.post("/admin/boat/1")
.header(ContentType::Form)
.body("name=Haichiii&amount_seats=1&location_id=999");
let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther);
assert_eq!(
response.headers().get("Location").next(),
Some("/admin/boat")
);
let flash_cookie = response
.cookies()
.get("_flash")
.expect("Expected flash cookie");
assert_eq!(
flash_cookie.value(),
"5:errorerror returned from database: (code: 787) FOREIGN KEY constraint failed"
);
}
#[sqlx::test]
fn test_succ_create() {
let db = testdb!();
let rocket = rocket::build().manage(db.clone());
let rocket = crate::tera::config(rocket);
assert!(Boat::find_by_name(&db, "completely-new-boat".into())
.await
.is_none());
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
.post("/admin/boat/new")
.header(ContentType::Form)
.body("name=completely-new-boat&amount_seats=1&location_id=1");
let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther);
assert_eq!(
response.headers().get("Location").next(),
Some("/admin/boat")
);
let flash_cookie = response
.cookies()
.get("_flash")
.expect("Expected flash cookie");
assert_eq!(flash_cookie.value(), "7:successBoot hinzugefügt");
Boat::find_by_name(&db, "completely-new-boat".into())
.await
.unwrap();
}
#[sqlx::test]
fn test_create_db_error() {
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
.post("/admin/boat/new")
.header(ContentType::Form)
.body("name=Haichenbach&amount_seats=1&location_id=1");
let response = req.dispatch().await;
assert_eq!(response.status(), Status::SeeOther);
assert_eq!(
response.headers().get("Location").next(),
Some("/admin/boat")
);
let flash_cookie = response
.cookies()
.get("_flash")
.expect("Expected flash cookie");
assert_eq!(
flash_cookie.value(),
"5:errorerror returned from database: (code: 2067) UNIQUE constraint failed: boat.name"
);
}
}