diff --git a/Rocket.toml b/Rocket.toml index 7be34da..d916684 100644 --- a/Rocket.toml +++ b/Rocket.toml @@ -1,5 +1,6 @@ [development.databases] stoptime_db = { url = "db/stoptime-dev.db" } +stoptime_test_db = { url = "db/stoptime-test.db" } [production.databases] stoptime_db = { url = "db/stoptime.db" } diff --git a/src/main.rs b/src/main.rs index 2c098e4..52ed43e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ extern crate diesel; #[macro_use] extern crate diesel_migrations; +use rocket::fairing::AdHoc; use rocket::{catchers, routes, Rocket}; use rocket_contrib::database; use rocket_contrib::serve::StaticFiles; @@ -24,11 +25,20 @@ pub mod schema; // the database. embed_migrations!(); +#[cfg(not(test))] #[database("stoptime_db")] pub struct DbConn(diesel::SqliteConnection); +#[cfg(test)] +#[database("stoptime_test_db")] +pub struct DbConn(diesel::SqliteConnection); + +#[cfg(test)] +pub mod seed; + /// Runs the database migrations. fn run_db_migrations(rocket: Rocket) -> Result { + println!(" => Running database migrations…"); let conn = DbConn::get_one(&rocket).expect("Failed to get a database connection"); match embedded_migrations::run(&*conn) { Ok(()) => Ok(rocket), @@ -39,6 +49,20 @@ fn run_db_migrations(rocket: Rocket) -> Result { } } +/// Run the database seeding (only during tests). +fn run_db_seeding(rocket: Rocket) -> Result { + #[cfg(test)] + { + println!(" => Running database seeding…"); + let conn = DbConn::get_one(&rocket).expect("Failed to get a database connection"); + if let Err(e) = crate::seed::run(conn) { + eprintln!("Failed to run database seeding: {:?}", e); + return Err(rocket); + } + } + Ok(rocket) +} + /// Sets up the Rocket application. fn rocket() -> Rocket { let static_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/static"); @@ -47,6 +71,7 @@ fn rocket() -> Rocket { rocket::ignite() .attach(DbConn::fairing()) .attach(AdHoc::on_attach("Database Migrations", run_db_migrations)) + .attach(AdHoc::on_attach("Database Seed", run_db_seeding)) .mount("/", routes![handlers::index]) .mount( "/company", diff --git a/src/rest_helpers.rs b/src/rest_helpers.rs index be1a133..ff5c886 100644 --- a/src/rest_helpers.rs +++ b/src/rest_helpers.rs @@ -62,3 +62,13 @@ macro_rules! delete { } }}; } + +macro_rules! destroy_all { + ($model_name:ident, $conn:expr) => {{ + use diesel::associations::HasTable; + use diesel::RunQueryDsl; + + let table = $crate::models::$model_name::table(); + diesel::delete(table).execute(&$conn) + }}; +} diff --git a/src/seed.rs b/src/seed.rs new file mode 100644 index 0000000..ac6f0b7 --- /dev/null +++ b/src/seed.rs @@ -0,0 +1,41 @@ +use diesel::prelude::*; + +use crate::models::{Customer, NewCustomer}; +use crate::DbConn; + +pub fn run(conn: DbConn) -> Result<(), &'static str> { + destroy_all!(Customer, *conn).map_err(|_| "Could not destroy all customers")?; + create!(Customer, new_customer("one"), *conn).expect("foo"); + create!(Customer, new_customer("two"), *conn).expect("foo"); + Ok(()) +} + +pub fn new_customer(key: &'static str) -> NewCustomer { + match key { + "one" => NewCustomer { + address_city: "Some City".to_string(), + address_postal_code: "123456".to_string(), + address_street: "Somestreet".to_string(), + email: "info@testcompany.tld".to_string(), + financial_contact: "Financial Office".to_string(), + hourly_rate: Some(100.0), + name: "Test Company".to_string(), + phone: "0123456789".to_string(), + short_name: "Test Co.".to_string(), + time_specification: true, + }, + "two" => NewCustomer { + address_city: "Other City".to_string(), + address_postal_code: "654321".to_string(), + address_street: "Otherstreet".to_string(), + email: "info@testcompany2.tld".to_string(), + financial_contact: "Financial Office".to_string(), + hourly_rate: None, + name: "Test Company 2".to_string(), + phone: "0987654321".to_string(), + short_name: "Test 2 Co.".to_string(), + time_specification: false, + }, + &_ => unimplemented!(), + } +}