From c5d5dcb323b08b4809bddb5fe4cbfbed9db8d096 Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Tue, 24 Sep 2024 15:44:48 +0530 Subject: [PATCH] feat: ordering: Kot ID is provided by caller & Kot view tests --- ...e5fc2837b3943b8bbcbade97920a99019c86.json} | 5 +- src/ordering/adapters/output/db/kot_view.rs | 185 +++++++++++++++++- .../adapters/output/db/line_item_view.rs | 15 +- .../adapters/output/db/order_id_exists.rs | 2 +- .../application/services/add_kot_service.rs | 20 +- .../services/add_line_item_service.rs | 16 +- src/ordering/domain/add_kot_command.rs | 4 + src/ordering/domain/kot_added_event.rs | 10 +- 8 files changed, 213 insertions(+), 44 deletions(-) rename .sqlx/{query-4b7100e5c7442066dbb4ea7c9733e038af635766f0be61a86ca7084b34a2109d.json => query-97c136fd927b9a153a6093da6594e5fc2837b3943b8bbcbade97920a99019c86.json} (67%) diff --git a/.sqlx/query-4b7100e5c7442066dbb4ea7c9733e038af635766f0be61a86ca7084b34a2109d.json b/.sqlx/query-97c136fd927b9a153a6093da6594e5fc2837b3943b8bbcbade97920a99019c86.json similarity index 67% rename from .sqlx/query-4b7100e5c7442066dbb4ea7c9733e038af635766f0be61a86ca7084b34a2109d.json rename to .sqlx/query-97c136fd927b9a153a6093da6594e5fc2837b3943b8bbcbade97920a99019c86.json index 2aeaf77..319c68c 100644 --- a/.sqlx/query-4b7100e5c7442066dbb4ea7c9733e038af635766f0be61a86ca7084b34a2109d.json +++ b/.sqlx/query-97c136fd927b9a153a6093da6594e5fc2837b3943b8bbcbade97920a99019c86.json @@ -1,18 +1,17 @@ { "db_name": "PostgreSQL", - "query": "UPDATE\n cqrs_ordering_kot_query\n SET\n version = $1,\n order_id = $2,\n kot_id = $3,\n created_time = $4,\n deleted = $5;", + "query": "UPDATE\n cqrs_ordering_kot_query\n SET\n version = $1,\n order_id = $2,\n created_time = $3,\n deleted = $4;", "describe": { "columns": [], "parameters": { "Left": [ "Int8", "Uuid", - "Uuid", "Timestamptz", "Bool" ] }, "nullable": [] }, - "hash": "4b7100e5c7442066dbb4ea7c9733e038af635766f0be61a86ca7084b34a2109d" + "hash": "97c136fd927b9a153a6093da6594e5fc2837b3943b8bbcbade97920a99019c86" } diff --git a/src/ordering/adapters/output/db/kot_view.rs b/src/ordering/adapters/output/db/kot_view.rs index 047da2a..2adccd8 100644 --- a/src/ordering/adapters/output/db/kot_view.rs +++ b/src/ordering/adapters/output/db/kot_view.rs @@ -197,12 +197,10 @@ impl ViewRepository for OrderingDBPostgresAdapter { SET version = $1, order_id = $2, - kot_id = $3, - created_time = $4, - deleted = $5;", + created_time = $3, + deleted = $4;", version, view.order_id, - view.kot_id, view.created_time, view.deleted, ) @@ -230,3 +228,182 @@ impl Query for OrderingDBPostgresAdapter { self.update_view(view, view_context).await.unwrap(); } } + +#[cfg(test)] +mod tests { + use super::*; + + use postgres_es::PostgresCqrs; + use time::macros::datetime; + + use crate::{ + db::migrate::*, + ordering::{ + application::services::{ + add_kot_service::AddKotServiceBuilder, delete_kot_service::DeleteKotServiceBuilder, + update_kot_service::*, MockOrderingServicesInterface, + }, + domain::{ + add_kot_command::*, commands::OrderingCommand, + delete_kot_command::DeleteKotCommandBuilder, order_aggregate::Order, + update_kot_command::*, + }, + }, + tests::bdd::*, + utils::{ + random_string::GenerateRandomStringInterface, + uuid::{tests::UUID, *}, + }, + }; + use std::sync::Arc; + + #[actix_rt::test] + async fn pg_query_ordering_kot_view() { + let settings = crate::settings::tests::get_settings().await; + //let settings = crate::settings::Settings::new().unwrap(); + settings.create_db().await; + + let uuid = GenerateUUID {}; + + let db = crate::db::sqlx_postgres::Postgres::init(&settings.database.url).await; + db.migrate().await; + let db = OrderingDBPostgresAdapter::new(db.pool.clone()); + + let order = Order::default(); + crate::ordering::adapters::output::db::order_id_exists::tests::create_dummy_order( + &order, &db, + ) + .await; + + let queries: Vec>> = vec![Box::new(db.clone())]; + + let mut mock_services = MockOrderingServicesInterface::new(); + + let db2 = db.clone(); + mock_services + .expect_add_kot() + .times(IS_CALLED_ONLY_ONCE.unwrap()) + .returning(move || { + Arc::new( + AddKotServiceBuilder::default() + .db_kot_id_exists(Arc::new(db2.clone())) + .db_order_id_exists(Arc::new(db2.clone())) + .build() + .unwrap(), + ) + }); + + let db2 = db.clone(); + mock_services + .expect_update_kot() + .times(IS_CALLED_ONLY_ONCE.unwrap()) + .returning(move || { + Arc::new( + UpdateKotServiceBuilder::default() + .db_kot_id_exists(Arc::new(db2.clone())) + .db_order_id_exists(Arc::new(db2.clone())) + .build() + .unwrap(), + ) + }); + + let db2 = db.clone(); + mock_services + .expect_delete_kot() + .times(IS_CALLED_ONLY_ONCE.unwrap()) + .returning(move || { + Arc::new( + DeleteKotServiceBuilder::default() + .db_kot_id_exists(Arc::new(db2.clone())) + .build() + .unwrap(), + ) + }); + + let (cqrs, kot_query): ( + Arc>, + Arc>, + ) = ( + Arc::new(postgres_es::postgres_cqrs( + db.pool.clone(), + queries, + Arc::new(mock_services), + )), + Arc::new(db.clone()), + ); + + let cmd = AddKotCommandBuilder::default() + .adding_by(UUID) + .created_time(datetime!(1970-01-01 0:00 UTC)) + .order_id(*order.order_id()) + .kot_id(uuid.get_uuid()) + .build() + .unwrap(); + + cqrs.execute( + &cmd.kot_id().to_string(), + OrderingCommand::AddKot(cmd.clone()), + ) + .await + .unwrap(); + + let kot = kot_query + .load(&(*cmd.kot_id()).to_string()) + .await + .unwrap() + .unwrap(); + let kot: Kot = kot.into(); + assert_eq!(kot.order_id(), cmd.order_id()); + assert_eq!(kot.kot_id(), cmd.kot_id()); + assert!(!kot.deleted()); + + // update + let update_kot_cmd = UpdateKotCommandBuilder::default() + .adding_by(UUID) + .created_time(datetime!(1970-01-01 1:00 UTC)) + .order_id(*order.order_id()) + .old_kot(kot.clone()) + .build() + .unwrap(); + cqrs.execute( + &cmd.kot_id().to_string(), + OrderingCommand::UpdateKot(update_kot_cmd.clone()), + ) + .await + .unwrap(); + let kot = kot_query + .load(&(*cmd.kot_id()).to_string()) + .await + .unwrap() + .unwrap(); + let kot: Kot = kot.into(); + assert_eq!(kot.order_id(), update_kot_cmd.order_id()); + assert_eq!(kot.kot_id(), update_kot_cmd.old_kot().kot_id()); + assert!(!kot.deleted()); + + // delete + let delete_kot_command = DeleteKotCommandBuilder::default() + .kot(kot.clone()) + .adding_by(UUID) + .build() + .unwrap(); + + cqrs.execute( + &cmd.kot_id().to_string(), + OrderingCommand::DeleteKot(delete_kot_command.clone()), + ) + .await + .unwrap(); + let kot = kot_query + .load(&(*cmd.kot_id()).to_string()) + .await + .unwrap() + .unwrap(); + let kot: Kot = kot.into(); + assert_eq!(kot.order_id(), delete_kot_command.kot().order_id()); + assert_eq!(kot.kot_id(), delete_kot_command.kot().kot_id()); + assert!(kot.deleted()); + + settings.drop_db().await; + } +} diff --git a/src/ordering/adapters/output/db/line_item_view.rs b/src/ordering/adapters/output/db/line_item_view.rs index 5fe5c2a..3e3fa33 100644 --- a/src/ordering/adapters/output/db/line_item_view.rs +++ b/src/ordering/adapters/output/db/line_item_view.rs @@ -319,7 +319,6 @@ impl Query for OrderingDBPostgresAdapter { } } - #[cfg(test)] mod tests { use super::*; @@ -327,18 +326,18 @@ mod tests { use postgres_es::PostgresCqrs; use crate::{ + db::migrate::*, ordering::{ application::services::{ add_line_item_service::AddLineItemServiceBuilder, delete_line_item_service::*, update_line_item_service::*, MockOrderingServicesInterface, }, domain::{ - add_line_item_command::*, kot_aggregate::Kot, commands::OrderingCommand, - delete_line_item_command::DeleteLineItemCommandBuilder, + add_line_item_command::*, commands::OrderingCommand, + delete_line_item_command::DeleteLineItemCommandBuilder, kot_aggregate::Kot, update_line_item_command::*, }, }, - db::migrate::*, tests::bdd::*, types::quantity::*, utils::{ @@ -363,10 +362,8 @@ mod tests { let mut mock_services = MockOrderingServicesInterface::new(); let kot = Kot::default(); - crate::ordering::adapters::output::db::kot_id_exists::tests::create_dummy_kot( - &kot, &db, - ) - .await; + crate::ordering::adapters::output::db::kot_id_exists::tests::create_dummy_kot(&kot, &db) + .await; let db2 = db.clone(); mock_services @@ -428,7 +425,6 @@ mod tests { let cmd = AddLineItemCommandBuilder::default() .product_name(rand.get_random(10)) .adding_by(UUID) - .quantity(Quantity::get_quantity()) .product_id(UUID) .kot_id(*kot.kot_id()) @@ -462,7 +458,6 @@ mod tests { .product_id(UUID) .kot_id(*kot.kot_id()) .old_line_item(line_item.clone()) - .build() .unwrap() .validate() diff --git a/src/ordering/adapters/output/db/order_id_exists.rs b/src/ordering/adapters/output/db/order_id_exists.rs index 5b5a99c..5f0f634 100644 --- a/src/ordering/adapters/output/db/order_id_exists.rs +++ b/src/ordering/adapters/output/db/order_id_exists.rs @@ -36,7 +36,7 @@ pub mod tests { // use crate::ordering::domain::add_order_command::tests::get_customizations; use crate::ordering::domain::order_aggregate::*; - async fn create_dummy_order(order: &Order, db: &OrderingDBPostgresAdapter) { + pub async fn create_dummy_order(order: &Order, db: &OrderingDBPostgresAdapter) { sqlx::query!( "INSERT INTO cqrs_ordering_order_query ( version, diff --git a/src/ordering/application/services/add_kot_service.rs b/src/ordering/application/services/add_kot_service.rs index 09edd5d..c04d874 100644 --- a/src/ordering/application/services/add_kot_service.rs +++ b/src/ordering/application/services/add_kot_service.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use derive_builder::Builder; use mockall::predicate::*; use mockall::*; -use time::OffsetDateTime; use super::errors::*; use crate::ordering::{ @@ -15,7 +14,6 @@ use crate::ordering::{ application::port::output::db::order_id_exists::*, domain::{add_kot_command::*, kot_added_event::*, kot_aggregate::*}, }; -use crate::utils::uuid::*; #[automock] #[async_trait::async_trait] @@ -29,7 +27,6 @@ pub type AddKotServiceObj = Arc; pub struct AddKotService { db_kot_id_exists: KotIDExistsDBPortObj, db_order_id_exists: OrderIDExistsDBPortObj, - get_uuid: GetUUIDInterfaceObj, } #[async_trait::async_trait] @@ -43,21 +40,14 @@ impl AddKotUseCase for AddKotService { return Err(OrderingError::OrderIDNotFound); } - let mut kot_id = self.get_uuid.get_uuid(); - - loop { - if self.db_kot_id_exists.kot_id_exists(&kot_id).await? { - kot_id = self.get_uuid.get_uuid(); - continue; - } else { - break; - } + if self.db_kot_id_exists.kot_id_exists(cmd.kot_id()).await? { + return Err(OrderingError::KotIDNotFound); } let kot = KotBuilder::default() .created_time(cmd.created_time().clone()) .order_id(*cmd.order_id()) - .kot_id(kot_id) + .kot_id(*cmd.kot_id()) .deleted(false) .build() .unwrap(); @@ -75,8 +65,8 @@ pub mod tests { use super::*; use crate::ordering::domain::kot_added_event::tests::get_added_kot_event_from_command; + use crate::tests::bdd::*; use crate::utils::uuid::tests::UUID; - use crate::{tests::bdd::*, utils::uuid::tests::mock_get_uuid}; pub fn mock_add_kot_service(times: Option, cmd: AddKotCommand) -> AddKotServiceObj { let mut m = MockAddKotUseCase::new(); @@ -100,7 +90,6 @@ pub mod tests { let s = AddKotServiceBuilder::default() .db_kot_id_exists(mock_kot_id_exists_db_port_false(IS_CALLED_ONLY_ONCE)) .db_order_id_exists(mock_order_id_exists_db_port_true(IS_CALLED_ONLY_ONCE)) - .get_uuid(mock_get_uuid(IS_CALLED_ONLY_ONCE)) .build() .unwrap(); @@ -118,7 +107,6 @@ pub mod tests { let s = AddKotServiceBuilder::default() .db_kot_id_exists(mock_kot_id_exists_db_port_false(IS_NEVER_CALLED)) .db_order_id_exists(mock_order_id_exists_db_port_false(IS_CALLED_ONLY_ONCE)) - .get_uuid(mock_get_uuid(IS_NEVER_CALLED)) .build() .unwrap(); diff --git a/src/ordering/application/services/add_line_item_service.rs b/src/ordering/application/services/add_line_item_service.rs index 1e5d573..ca329be 100644 --- a/src/ordering/application/services/add_line_item_service.rs +++ b/src/ordering/application/services/add_line_item_service.rs @@ -37,13 +37,13 @@ impl AddLineItemUseCase for AddLineItemService { return Err(OrderingError::KotIDNotFound); } - if self - .db_line_item_id_exists - .line_item_id_exists(cmd.line_item_id()) - .await? - { - return Err(OrderingError::DuplicateLineItemID); - } + if self + .db_line_item_id_exists + .line_item_id_exists(cmd.line_item_id()) + .await? + { + return Err(OrderingError::DuplicateLineItemID); + } let line_item = LineItemBuilder::default() .created_time(cmd.created_time().clone()) @@ -69,8 +69,8 @@ pub mod tests { use super::*; use crate::ordering::domain::line_item_added_event::tests::get_added_line_item_event_from_command; - use crate::utils::uuid::tests::UUID; use crate::tests::bdd::*; + use crate::utils::uuid::tests::UUID; pub fn mock_add_line_item_service( times: Option, diff --git a/src/ordering/domain/add_kot_command.rs b/src/ordering/domain/add_kot_command.rs index 597330a..6fdd91e 100644 --- a/src/ordering/domain/add_kot_command.rs +++ b/src/ordering/domain/add_kot_command.rs @@ -17,6 +17,7 @@ pub struct AddKotCommand { #[builder(default = "OffsetDateTime::now_utc()")] created_time: OffsetDateTime, order_id: Uuid, + kot_id: Uuid, } #[cfg(test)] @@ -36,6 +37,7 @@ mod tests { .adding_by(adding_by) .created_time(datetime!(1970-01-01 0:00 UTC)) .order_id(order_id) + .kot_id(UUID) .build() .unwrap() } @@ -49,10 +51,12 @@ mod tests { let cmd = AddKotCommandBuilder::default() .adding_by(adding_by) .order_id(order_id) + .kot_id(UUID) .build() .unwrap(); assert_eq!(*cmd.order_id(), order_id); + assert_eq!(*cmd.kot_id(), UUID); assert_eq!(*cmd.adding_by(), adding_by); } } diff --git a/src/ordering/domain/kot_added_event.rs b/src/ordering/domain/kot_added_event.rs index 26fd5f6..eb33ff5 100644 --- a/src/ordering/domain/kot_added_event.rs +++ b/src/ordering/domain/kot_added_event.rs @@ -20,12 +20,18 @@ pub struct KotAddedEvent { #[cfg(test)] pub mod tests { - use crate::ordering::domain::add_kot_command::AddKotCommand; + use crate::ordering::domain::{add_kot_command::AddKotCommand, kot_aggregate::*}; use super::*; pub fn get_added_kot_event_from_command(cmd: &AddKotCommand) -> KotAddedEvent { - let kot = Kot::get_kot(); + let kot = KotBuilder::default() + .created_time(cmd.created_time().clone()) + .order_id(*cmd.order_id()) + .kot_id(*cmd.kot_id()) + .deleted(false) + .build() + .unwrap(); KotAddedEventBuilder::default() .added_by_user(cmd.adding_by().clone())