diff --git a/src/inventory/adapters/input/web/customization.rs b/src/inventory/adapters/input/web/customization.rs new file mode 100644 index 0000000..fb954ec --- /dev/null +++ b/src/inventory/adapters/input/web/customization.rs @@ -0,0 +1,118 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use actix_identity::Identity; +use actix_web::{get, http::header::ContentType, post, web, HttpRequest, HttpResponse, Responder}; +use derive_builder::Builder; +use serde::{Deserialize, Serialize}; +use url::Url; +use uuid::Uuid; + +use super::errors::*; +use super::types; +//use crate::utils::uuid::WebGetUUIDInterfaceObj; + +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(add_customization_ui_handler); + cfg.service(add_customization_form_submission_handler); + cfg.service(update_customization_ui_handler); + cfg.service(update_customization_form_submission_handler); +} + +// add_customization handlers + +#[allow(clippy::too_many_arguments)] +#[get("/inventory/{category_uuid}/{product_uuid}/customization/add")] +#[tracing::instrument(name = "add_customization UI handler", skip())] +async fn add_customization_ui_handler() -> WebJsonRepsonse { + use web_ui::inventory::add_customization::*; + + let page = AddCustomizationPage::page(); + + Ok(HttpResponse::Ok() + .insert_header(ContentType::html()) + .body(page)) +} + +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +struct AddCustomizationPayload { + password: String, +} + +#[allow(clippy::too_many_arguments)] +#[post("/inventory/{category_uuid}/{product_uuid}/customization/add")] +#[tracing::instrument( + name = "add_customization form submission handler" + skip(id, req, payload, inventory_cqrs_exec) + )] +async fn add_customization_form_submission_handler( + inventory_cqrs_exec: types::WebInventoryCqrsExec, + req: HttpRequest, + id: Identity, + payload: web::Form, +) -> WebJsonRepsonse { + let store = ""; + + Ok(HttpResponse::Ok().json(store)) +} + +// update_customization handlers + +#[allow(clippy::too_many_arguments)] +#[get("/inventory/{category_uuid}/{product_uuid}/{customization_uuid}/update")] +#[tracing::instrument(name = "update_customization UI handler", skip())] +async fn update_customization_ui_handler() -> WebJsonRepsonse { + use web_ui::inventory::update_customization::*; + + let page = UpdateCustomizationPage::page(); + + Ok(HttpResponse::Ok() + .insert_header(ContentType::html()) + .body(page)) +} + +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +struct UpdateCustomizationPayload { + password: String, +} + +#[allow(clippy::too_many_arguments)] +#[post("/inventory/{category_uuid}/{product_uuid}/{customization_uuid}/update")] +#[tracing::instrument( + name = "update_customization form submission handler" + skip(id, req, payload, inventory_cqrs_exec) + )] +async fn update_customization_form_submission_handler( + inventory_cqrs_exec: types::WebInventoryCqrsExec, + req: HttpRequest, + id: Identity, + payload: web::Form, +) -> WebJsonRepsonse { + let store = ""; + + Ok(HttpResponse::Ok().json(store)) +} + +#[cfg(test)] +mod tests { + use crate::utils::uuid::tests::UUID; + + use super::*; + + #[actix_rt::test] + async fn inventory_web_add_customization_ui_works() { + let routes = crate::inventory::adapters::input::web::RoutesRepository::default(); + crate::tests::actix_web_test_utils::page_test_runner(&routes.add_customization(UUID, UUID)) + .await; + } + + #[actix_rt::test] + async fn inventory_web_update_customization_ui_works() { + let routes = crate::inventory::adapters::input::web::RoutesRepository::default(); + crate::tests::actix_web_test_utils::page_test_runner( + &routes.update_customization(UUID, UUID, UUID), + ) + .await; + } +} diff --git a/src/inventory/adapters/input/web/mod.rs b/src/inventory/adapters/input/web/mod.rs index 88a4b6e..1fe5c73 100644 --- a/src/inventory/adapters/input/web/mod.rs +++ b/src/inventory/adapters/input/web/mod.rs @@ -10,7 +10,9 @@ use crate::inventory::adapters::types; //mod employee; mod category; +mod customization; mod errors; +mod product; mod routes; pub use errors::WebJsonRepsonse; @@ -22,6 +24,8 @@ pub fn load_ctx() -> impl FnOnce(&mut web::ServiceConfig) { let f = move |cfg: &mut web::ServiceConfig| { cfg.app_data(routes); + cfg.configure(customization::services); + cfg.configure(product::services); cfg.configure(category::services); }; diff --git a/src/inventory/adapters/input/web/product.rs b/src/inventory/adapters/input/web/product.rs new file mode 100644 index 0000000..4fed1f7 --- /dev/null +++ b/src/inventory/adapters/input/web/product.rs @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: 2024 Aravinth Manivannan +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +use actix_identity::Identity; +use actix_web::{get, http::header::ContentType, post, web, HttpRequest, HttpResponse, Responder}; +use derive_builder::Builder; +use serde::{Deserialize, Serialize}; +use url::Url; +use uuid::Uuid; + +use super::errors::*; +use super::types; +//use crate::utils::uuid::WebGetUUIDInterfaceObj; + +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(add_product_ui_handler); + cfg.service(add_product_form_submission_handler); + cfg.service(update_product_ui_handler); + cfg.service(update_product_form_submission_handler); +} + +// add_product handlers + +#[allow(clippy::too_many_arguments)] +#[get("/inventory/{category_uuid}/product/add")] +#[tracing::instrument(name = "add_product UI handler", skip())] +async fn add_product_ui_handler() -> WebJsonRepsonse { + use web_ui::inventory::add_product::*; + + let page = AddProductPage::page(); + + Ok(HttpResponse::Ok() + .insert_header(ContentType::html()) + .body(page)) +} + +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +struct AddProductPagePayload { + password: String, +} + +#[allow(clippy::too_many_arguments)] +#[post("/inventory/{category_uuid}/product/add")] +#[tracing::instrument( + name = "add_product form submission handler" + skip(id, req, payload, inventory_cqrs_exec) + )] +async fn add_product_form_submission_handler( + inventory_cqrs_exec: types::WebInventoryCqrsExec, + req: HttpRequest, + id: Identity, + payload: web::Form, +) -> WebJsonRepsonse { + let store = ""; + + Ok(HttpResponse::Ok().json(store)) +} + +// update_product handlers + +#[allow(clippy::too_many_arguments)] +#[get("/inventory/{category_uuid}/{product_uuid}/update")] +#[tracing::instrument(name = "update_product UI handler", skip())] +async fn update_product_ui_handler() -> WebJsonRepsonse { + use web_ui::inventory::update_product::*; + + let page = UpdateProductPage::page(); + + Ok(HttpResponse::Ok() + .insert_header(ContentType::html()) + .body(page)) +} + +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] +struct UpdateProductPagePayload { + password: String, +} + +#[allow(clippy::too_many_arguments)] +#[post("/inventory/{category_uuid}/{product_uuid}/update")] +#[tracing::instrument( + name = "update_product form submission handler" + skip(id, req, payload, inventory_cqrs_exec) + )] +async fn update_product_form_submission_handler( + inventory_cqrs_exec: types::WebInventoryCqrsExec, + req: HttpRequest, + id: Identity, + payload: web::Form, +) -> WebJsonRepsonse { + let store = ""; + + Ok(HttpResponse::Ok().json(store)) +} + +#[cfg(test)] +mod tests { + use crate::utils::uuid::tests::UUID; + + use super::*; + + #[actix_rt::test] + async fn inventory_web_add_product_ui_works() { + let routes = crate::inventory::adapters::input::web::RoutesRepository::default(); + crate::tests::actix_web_test_utils::page_test_runner(&routes.add_product(UUID)).await; + } + + #[actix_rt::test] + async fn inventory_web_update_product_ui_works() { + let routes = crate::inventory::adapters::input::web::RoutesRepository::default(); + crate::tests::actix_web_test_utils::page_test_runner(&routes.update_product(UUID, UUID)) + .await; + } +} diff --git a/src/inventory/adapters/input/web/routes.rs b/src/inventory/adapters/input/web/routes.rs index 9c6c749..409ab0e 100644 --- a/src/inventory/adapters/input/web/routes.rs +++ b/src/inventory/adapters/input/web/routes.rs @@ -22,7 +22,7 @@ impl Default for RoutesRepository { update_category: "/inventory/{category_uuid}/update".into(), add_product: "/inventory/{category_uuid}/product/add".into(), - update_product: "/inventory/{category_uuid}/update".into(), + update_product: "/inventory/{category_uuid}/{product_uuid}/update".into(), add_customization: "/inventory/{category_uuid}/{product_uuid}/customization/add".into(), update_customization: @@ -36,6 +36,34 @@ impl RoutesRepository { self.update_category .replace("{category_uuid}", &category_uuid.to_string()) } + + pub fn add_product(&self, category_uuid: Uuid) -> String { + self.add_product + .replace("{category_uuid}", &category_uuid.to_string()) + } + pub fn update_product(&self, category_uuid: Uuid, product_uuid: Uuid) -> String { + self.update_product + .replace("{category_uuid}", &category_uuid.to_string()) + .replace("{product_uuid}", &product_uuid.to_string()) + } + + pub fn add_customization(&self, category_uuid: Uuid, product_uuid: Uuid) -> String { + self.add_customization + .replace("{category_uuid}", &category_uuid.to_string()) + .replace("{product_uuid}", &product_uuid.to_string()) + } + + pub fn update_customization( + &self, + category_uuid: Uuid, + product_uuid: Uuid, + customization_uuid: Uuid, + ) -> String { + self.update_customization + .replace("{category_uuid}", &category_uuid.to_string()) + .replace("{product_uuid}", &product_uuid.to_string()) + .replace("{customization_uuid}", &customization_uuid.to_string()) + } } #[cfg(test)] @@ -45,8 +73,48 @@ mod tests { use super::*; #[test] - fn inventory_update_category_route() { + fn inventory_web_route_update_category() { let r = RoutesRepository::default(); assert_eq!(r.update_category(UUID), format!("/inventory/{UUID}/update")); } + + #[test] + fn inventory_web_route_add_product() { + let r = RoutesRepository::default(); + assert_eq!( + r.add_product(UUID), + format!("/inventory/{UUID}/product/add") + ); + } + + #[test] + fn inventory_web_route_update_product() { + let r = RoutesRepository::default(); + let product_id = Uuid::new_v4(); + assert_eq!( + r.update_product(UUID, product_id), + format!("/inventory/{UUID}/{product_id}/update") + ); + } + + #[test] + fn inventory_web_route_add_customization() { + let r = RoutesRepository::default(); + let product_id = Uuid::new_v4(); + assert_eq!( + r.add_customization(UUID, product_id), + format!("/inventory/{UUID}/{product_id}/customization/add") + ); + } + + #[test] + fn inventory_web_route_update_customization() { + let r = RoutesRepository::default(); + let product_id = Uuid::new_v4(); + let customization_id = Uuid::new_v4(); + assert_eq!( + r.update_customization(UUID, product_id, customization_id), + format!("/inventory/{UUID}/{product_id}/{customization_id}/update") + ); + } }