From fcfe91708ec31821b8dfd82c358519299724d27f Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Tue, 16 Jul 2024 17:21:15 +0530 Subject: [PATCH] fix: consistency check for category before creating product --- .../services/add_product_service.rs | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/inventory/application/services/add_product_service.rs b/src/inventory/application/services/add_product_service.rs index 2030090..a446bc9 100644 --- a/src/inventory/application/services/add_product_service.rs +++ b/src/inventory/application/services/add_product_service.rs @@ -10,7 +10,9 @@ use mockall::*; use super::errors::*; use crate::inventory::{ - application::port::output::db::{product_id_exists::*, product_name_exists_for_category::*}, + application::port::output::db::{ + category_id_exists::*, product_id_exists::*, product_name_exists_for_category::*, + }, domain::{ add_product_command::AddProductCommand, product_added_event::{ProductAddedEvent, ProductAddedEventBuilder}, @@ -29,7 +31,7 @@ pub type AddProductServiceObj = Arc; #[derive(Clone, Builder)] pub struct AddProductService { - // TODO: check if category ID exists + db_category_id_exists: CategoryIDExistsDBPortObj, db_product_name_exists_for_category: ProductNameExistsForCategoryDBPortObj, db_product_id_exists: ProductIDExistsDBPortObj, get_uuid: GetUUIDInterfaceObj, @@ -38,6 +40,14 @@ pub struct AddProductService { #[async_trait::async_trait] impl AddProductUseCase for AddProductService { async fn add_product(&self, cmd: AddProductCommand) -> InventoryResult { + if !self + .db_category_id_exists + .category_id_exists(cmd.category_id()) + .await? + { + return Err(InventoryError::CategoryIDNotFound); + } + let mut product_id = self.get_uuid.get_uuid(); loop { @@ -138,6 +148,7 @@ pub mod tests { mock_product_name_exists_for_category_db_port_false(IS_CALLED_ONLY_ONCE), ) .db_product_id_exists(mock_product_id_exists_db_port_false(IS_CALLED_ONLY_ONCE)) + .db_category_id_exists(mock_category_id_exists_db_port_true(IS_CALLED_ONLY_ONCE)) .get_uuid(mock_get_uuid(IS_CALLED_ONLY_ONCE)) .build() .unwrap(); @@ -162,6 +173,7 @@ pub mod tests { .db_product_name_exists_for_category( mock_product_name_exists_for_category_db_port_true(IS_CALLED_ONLY_ONCE), ) + .db_category_id_exists(mock_category_id_exists_db_port_true(IS_CALLED_ONLY_ONCE)) .get_uuid(mock_get_uuid(IS_CALLED_ONLY_ONCE)) .db_product_id_exists(mock_product_id_exists_db_port_false(IS_CALLED_ONLY_ONCE)) .build() @@ -172,4 +184,24 @@ pub mod tests { Err(InventoryError::DuplicateProductName) ) } + + #[actix_rt::test] + async fn test_service_category_id_doesnt_exist() { + let cmd = get_command(); + + let s = AddProductServiceBuilder::default() + .db_product_name_exists_for_category( + mock_product_name_exists_for_category_db_port_false(IS_NEVER_CALLED), + ) + .db_product_id_exists(mock_product_id_exists_db_port_false(IS_NEVER_CALLED)) + .db_category_id_exists(mock_category_id_exists_db_port_false(IS_CALLED_ONLY_ONCE)) + .get_uuid(mock_get_uuid(IS_NEVER_CALLED)) + .build() + .unwrap(); + + assert_eq!( + s.add_product(cmd.clone()).await, + Err(InventoryError::CategoryIDNotFound) + ) + } }