//! The customer handlers //! //! Handlers for viewing a list of existing customers or creating a new one. use diesel::prelude::*; use rocket::{delete, get, post, put, uri}; use rocket_contrib::json::Json; use crate::models::{Customer, NewCustomer}; use crate::rest_helpers::*; use crate::DbConn; pub mod invoices; pub mod tasks; /// Shows the list of customers. #[get("/")] pub fn index(conn: DbConn) -> JsonResponse> { all!(Customer, *conn).into_json_response() } /// Creates a customer from the new customer #[post("/", format = "json", data = "")] pub fn create(new_customer: Json, conn: DbConn) -> CreatedJsonResponse { let new_customer = new_customer.into_inner(); create!(Customer, new_customer, *conn).into_created_json_response(|customer: &Customer| { uri!("/customers", show: customer.id).to_string() }) } /// Provides the form for the data required to create a new customer. #[get("/new")] pub fn new() -> JsonResponse { NewCustomer::default().into_json_response() } /// Shows a form for viewing and updating information of the customer with the given ID. #[get("/")] pub fn show(id: i32, conn: DbConn) -> JsonResponse { get!(Customer, id, *conn).into_json_response() } /// Updates the customer with the given ID. #[put("/", format = "json", data = "")] pub fn update(id: i32, customer: Json, conn: DbConn) -> JsonResponse { let customer = customer.into_inner(); update!(Customer, id, customer, *conn).into_json_response() } /// Destroys the customer with the given ID and redirects to the index handler. #[delete("/")] pub fn destroy(id: i32, conn: DbConn) -> NoContentResponse { destroy!(Customer, id, *conn).into_no_content_response() } #[cfg(test)] mod tests { use rocket::http::{Accept, ContentType, Status}; use serde_json::{self, json}; use super::*; macro_rules! run_test { (|$client:ident, $conn:ident| $block:expr) => {{ let rocket = crate::rocket(); let db = crate::DbConn::get_one(&rocket); let $conn = db.expect("Failed to get database connection for testing"); let $client = rocket::local::Client::new(rocket).expect("Failed to set up Rocket client"); $block }}; } #[test] fn index() { run_test!(|client, _conn| { let mut res = client.get("/customers").header(Accept::JSON).dispatch(); assert_eq!(res.status(), Status::Ok); let body = res.body_string().unwrap(); let customers = serde_json::from_str::>(body.as_str()).unwrap(); assert_eq!(customers.len(), 2); }); } #[test] fn create() { run_test!(|client, conn| { let new_customer_json = json!({ "name": "Test Company" }); let res = client .post("/customers") .header(ContentType::JSON) .header(Accept::JSON) .body(new_customer_json.to_string()) .dispatch(); assert_eq!(res.status(), Status::UnprocessableEntity); let customers: Vec = all!(Customer, *conn).expect("Customers"); let new_customer_json = json!({ "address_city": "Some City", "address_postal_code": "123456", "address_street": "Somestreet", "email": "info@testcompany.tld", "financial_contact": "Financial Office", "hourly_rate": 100.0, "name": "New Test Company", "phone": "0123456789", "short_name": "Test Co.", "time_specification": true, }); let mut res = client .post("/customers") .header(ContentType::JSON) .header(Accept::JSON) .body(new_customer_json.to_string()) .dispatch(); assert_eq!(res.status(), Status::Created); let body = res.body_string().unwrap(); let customer = serde_json::from_str::(body.as_str()).unwrap(); assert_eq!(customer.name, "New Test Company"); let customers_after: Vec = all!(Customer, *conn).expect("Customers"); assert_eq!(customers_after.len(), customers.len() + 1); }) } #[test] fn new() {} #[test] fn show() {} #[test] fn update() {} #[test] fn destroy() {} }