From ed66a074edd669f79bb9281a0ae9d846d2b71cec Mon Sep 17 00:00:00 2001 From: Aravinth Manivannan Date: Tue, 23 Jul 2024 20:34:04 +0530 Subject: [PATCH] feat: define Kot aggregate --- src/ordering/domain/kot_aggregate.rs | 168 ++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 2 deletions(-) diff --git a/src/ordering/domain/kot_aggregate.rs b/src/ordering/domain/kot_aggregate.rs index 4276087..16004cf 100644 --- a/src/ordering/domain/kot_aggregate.rs +++ b/src/ordering/domain/kot_aggregate.rs @@ -10,7 +10,10 @@ use serde::{Deserialize, Serialize}; use time::OffsetDateTime; use uuid::Uuid; -use super::line_item_aggregate::*; +use crate::ordering::{ + application::services::{errors::*, *}, + domain::{commands::*, events::*}, +}; #[derive( Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Builder, Getters, @@ -18,9 +21,170 @@ use super::line_item_aggregate::*; pub struct Kot { #[builder(default = "OffsetDateTime::now_utc()")] created_time: OffsetDateTime, - line_items: Vec, + // kots: Vec, kot_id: Uuid, order_id: Uuid, #[builder(default = "false")] deleted: bool, } + +impl Default for Kot { + fn default() -> Self { + Self { + created_time: OffsetDateTime::now_utc(), + order_id: Default::default(), + kot_id: Default::default(), + deleted: false, + } + } +} + +#[cfg(test)] +mod tests { + use crate::{ordering::domain::add_kot_command::AddKotCommand, utils::uuid::tests::UUID}; + + use super::*; + + impl Kot { + pub fn get_kot() -> Self { + let cmd = AddKotCommand::get_cmd(); + + KotBuilder::default() + .created_time(cmd.created_time().clone()) + .order_id(*cmd.order_id()) + .kot_id(UUID) + .build() + .unwrap() + } + } +} + +#[async_trait] +impl Aggregate for Kot { + type Command = OrderingCommand; + type Event = OrderingEvent; + type Error = OrderingError; + type Services = std::sync::Arc; + + // This identifier should be unique to the system. + fn aggregate_type() -> String { + "ordering.kot".to_string() + } + + // The aggregate logic goes here. Note that this will be the _bulk_ of a CQRS system + // so expect to use helper functions elsewhere to keep the code clean. + async fn handle( + &self, + command: Self::Command, + services: &Self::Services, + ) -> Result, Self::Error> { + match command { + OrderingCommand::AddKot(cmd) => { + let res = services.add_kot().add_kot(cmd).await?; + Ok(vec![OrderingEvent::KotAdded(res)]) + } + //OrderingCommand::UpdateKot(cmd) => { + // let res = services.update_kot().update_kot(cmd).await?; + // Ok(vec![OrderingEvent::KotUpdated(res)]) + //} + //OrderingCommand::DeleteKot(cmd) => { + // let res = services.delete_kot().delete_kot(cmd).await?; + // Ok(vec![OrderingEvent::KotDeleted(res)]) + //} + _ => Ok(Vec::default()), + } + } + + fn apply(&mut self, event: Self::Event) { + match event { + OrderingEvent::KotAdded(e) => *self = e.kot().clone(), + //OrderingEvent::KotUpdated(e) => *self = e.new_kot().clone(), + //OrderingEvent::KotDeleted(e) => *self = e.kot().clone(), + _ => (), + } + } +} + +#[cfg(test)] +mod aggregate_tests { + use std::sync::Arc; + + use add_kot_service::tests::mock_add_kot_service; + use cqrs_es::test::TestFramework; + // use delete_kot_service::tests::mock_delete_kot_service; + // use update_kot_service::tests::mock_update_kot_service; + + use super::*; + + // use crate::ordering::domain::delete_kot_command::DeleteKotCommand; + // use crate::ordering::domain::kot_deleted_event::tests::get_deleted_kot_event_from_command; + // use crate::ordering::domain::kot_updated_event::tests::get_updated_kot_event_from_command; + // use crate::ordering::domain::update_kot_command::UpdateKotCommand; + use crate::tests::bdd::*; + + use crate::ordering::domain::{ + add_kot_command::*, kot_added_event::tests::get_added_kot_event_from_command, + }; + + type KotTestFramework = TestFramework; + + #[test] + fn test_add_kot() { + let cmd = AddKotCommand::get_cmd(); + let expected = get_added_kot_event_from_command(&cmd); + let expected = OrderingEvent::KotAdded(expected); + + let mut services = MockOrderingServicesInterface::new(); + services + .expect_add_kot() + .times(IS_CALLED_ONLY_ONCE.unwrap()) + .return_const(mock_add_kot_service(IS_CALLED_ONLY_ONCE, cmd.clone())); + + KotTestFramework::with(Arc::new(services)) + .given_no_previous_events() + .when(OrderingCommand::AddKot(cmd)) + .then_expect_events(vec![expected]); + } + + // #[test] + // fn test_update_kot() { + // let cmd = UpdateKotCommand::get_cmd(); + // let expected = get_updated_kot_event_from_command(&cmd); + // let expected = OrderingEvent::KotUpdated(expected); + // + // let mut services = MockOrderingServicesInterface::new(); + // services + // .expect_update_kot() + // .times(IS_CALLED_ONLY_ONCE.unwrap()) + // .return_const(mock_update_kot_service( + // IS_CALLED_ONLY_ONCE, + // cmd.clone(), + // )); + // + // KotTestFramework::with(Arc::new(services)) + // .given_no_previous_events() + // .when(OrderingCommand::UpdateKot(cmd)) + // .then_expect_events(vec![expected]); + // } + // + // #[test] + // fn test_delete_kot() { + // let cmd = DeleteKotCommand::get_cmd(); + // let expected = get_deleted_kot_event_from_command(&cmd); + // let expected = OrderingEvent::KotDeleted(expected); + // + // let mut services = MockOrderingServicesInterface::new(); + // services + // .expect_delete_kot() + // .times(IS_CALLED_ONLY_ONCE.unwrap()) + // .return_const(mock_delete_kot_service( + // IS_CALLED_ONLY_ONCE, + // cmd.clone(), + // )); + // + // KotTestFramework::with(Arc::new(services)) + // .given_no_previous_events() + // .when(OrderingCommand::DeleteKot(cmd)) + // .then_expect_events(vec![expected]); + // } +}