diff --git a/entity/src/lib.rs b/entity/src/lib.rs index ce0d1cc..21a8496 100644 --- a/entity/src/lib.rs +++ b/entity/src/lib.rs @@ -1,2 +1,4 @@ mod entities; +pub mod wrappers; + pub use entities::{prelude::*, *}; diff --git a/entity/src/wrappers/mod.rs b/entity/src/wrappers/mod.rs new file mode 100644 index 0000000..9ff0ee6 --- /dev/null +++ b/entity/src/wrappers/mod.rs @@ -0,0 +1,122 @@ +use crate::entities::submission; +use sea_orm::{ActiveValue, IntoActiveModel}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Submission { + pub first_name: String, + pub last_name: String, + pub title: Option, + pub organization: Option, + pub email: String, + pub country: String, + pub city: String, + pub region: Option, + pub fips_code: String, + pub consent: bool, +} + +impl IntoActiveModel for Submission { + fn into_active_model(self) -> submission::ActiveModel { + submission::ActiveModel { + id: ActiveValue::NotSet, + first_name: ActiveValue::Set(self.first_name), + last_name: ActiveValue::Set(self.last_name), + title: ActiveValue::Set(self.title), + organization: ActiveValue::Set(self.organization), + email: ActiveValue::Set(self.email), + country: ActiveValue::Set(self.country), + city: ActiveValue::Set(self.city), + region: ActiveValue::Set(self.region), + fips_code: ActiveValue::Set(self.fips_code), + consent: ActiveValue::Set(self.consent), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_submission_into_active_model_full() { + let first_name = "John".to_string(); + let last_name = "Doe".to_string(); + let title = Some("Director".to_owned()); + let organization = Some("ACME".to_string()); + let email = "john.doe@acme.org".to_string(); + let country = "usa".to_string(); + let city = "austin".to_string(); + let region = Some("texas".to_string()); + let fips_code = "0123456".to_string(); + let consent = true; + let wrapper = Submission { + first_name: first_name.clone(), + last_name: last_name.clone(), + title: title.clone(), + organization: organization.clone(), + email: email.clone(), + country: country.clone(), + city: city.clone(), + region: region.clone(), + fips_code: fips_code.clone(), + consent, + }; + let active_model = wrapper.into_active_model(); + let expected = submission::ActiveModel { + id: ActiveValue::NotSet, + first_name: ActiveValue::Set(first_name), + last_name: ActiveValue::Set(last_name), + title: ActiveValue::Set(title), + organization: ActiveValue::Set(organization), + email: ActiveValue::Set(email), + country: ActiveValue::Set(country), + city: ActiveValue::Set(city), + region: ActiveValue::Set(region), + fips_code: ActiveValue::Set(fips_code), + consent: ActiveValue::Set(consent), + }; + assert_eq!(active_model, expected); + } + + #[test] + fn test_submission_into_active_model_required_only() { + let first_name = "John".to_string(); + let last_name = "Doe".to_string(); + let title = None; + let organization = None; + let email = "john.doe@acme.org".to_string(); + let country = "usa".to_string(); + let city = "austin".to_string(); + let region = None; + let fips_code = "0123456".to_string(); + let consent = true; + let wrapper = Submission { + first_name: first_name.clone(), + last_name: last_name.clone(), + title: title.clone(), + organization: organization.clone(), + email: email.clone(), + country: country.clone(), + city: city.clone(), + region: region.clone(), + fips_code: fips_code.clone(), + consent, + }; + let active_model = wrapper.into_active_model(); + let expected = submission::ActiveModel { + id: ActiveValue::NotSet, + first_name: ActiveValue::Set(first_name), + last_name: ActiveValue::Set(last_name), + title: ActiveValue::Set(title), + organization: ActiveValue::Set(organization), + email: ActiveValue::Set(email), + country: ActiveValue::Set(country), + city: ActiveValue::Set(city), + region: ActiveValue::Set(region), + fips_code: ActiveValue::Set(fips_code), + consent: ActiveValue::Set(consent), + }; + assert_eq!(active_model, expected); + } +} diff --git a/lambdas/src/submissions/post-submissions-city.rs b/lambdas/src/submissions/post-submissions-city.rs index 1ec6f8c..d64ff4f 100644 --- a/lambdas/src/submissions/post-submissions-city.rs +++ b/lambdas/src/submissions/post-submissions-city.rs @@ -1,28 +1,13 @@ use dotenv::dotenv; -use entity::submission; +use entity::{prelude::*, wrappers}; use lambda_http::{ http::StatusCode, run, service_fn, Body, Error, IntoResponse, Request, Response, }; use lambdas::{database_connect, get_apigw_request_id, APIError, APIErrorSource, APIErrors}; -use sea_orm::{ActiveValue, EntityTrait}; -use serde::{Deserialize, Serialize}; +use sea_orm::{EntityTrait, IntoActiveModel}; use serde_json::json; use tracing::info; -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct SubmissionWrapper { - pub first_name: String, - pub last_name: String, - pub title: Option, - pub organization: Option, - pub email: String, - pub country: String, - pub city: String, - pub region: Option, - pub fips_code: String, - pub consent: bool, -} - async fn function_handler(event: Request) -> Result, Error> { dotenv().ok(); @@ -34,7 +19,7 @@ async fn function_handler(event: Request) -> Result, Error> { let body = event.body(); let body_str = std::str::from_utf8(body).expect("invalid utf-8 sequence"); info!(body_str); - let wrapper = match serde_json::from_str::(body_str) { + let wrapper = match serde_json::from_str::(body_str) { Ok(model) => model, Err(e) => { let api_error = APIError::new( @@ -49,28 +34,14 @@ async fn function_handler(event: Request) -> Result, Error> { }; // Turn the model wrapper into an active model and unset the primary key. - let active_submission = submission::ActiveModel { - id: ActiveValue::NotSet, - first_name: ActiveValue::Set(wrapper.first_name), - last_name: ActiveValue::Set(wrapper.last_name), - title: ActiveValue::Set(wrapper.title), - organization: ActiveValue::Set(wrapper.organization), - email: ActiveValue::Set(wrapper.email), - country: ActiveValue::Set(wrapper.country), - city: ActiveValue::Set(wrapper.city), - region: ActiveValue::Set(wrapper.region), - fips_code: ActiveValue::Set(wrapper.fips_code), - consent: ActiveValue::Set(wrapper.consent), - }; + let active_submission = wrapper.into_active_model(); info!( "inserting Submission into database: {:?}", active_submission ); // Insert the submission into the database. - let res = submission::Entity::insert(active_submission) - .exec(&db) - .await?; + let res = Submission::insert(active_submission).exec(&db).await?; Ok(json!(res.last_insert_id).into_response().await) }