feat: define LineItem with add and update events and commands
This commit is contained in:
parent
06c97f57a2
commit
ac1964d21a
13 changed files with 697 additions and 0 deletions
153
src/ordering/domain/add_line_item_command.rs
Normal file
153
src/ordering/domain/add_line_item_command.rs
Normal file
|
@ -0,0 +1,153 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use derive_more::{Display, Error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::types::quantity::*;
|
||||
use crate::utils::string::empty_string_err;
|
||||
|
||||
#[derive(Debug, Error, Display, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum AddLineItemCommandError {
|
||||
QuantityIsEmpty,
|
||||
ProductNameIsEmpty,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||||
)]
|
||||
pub struct UnvalidatedAddLineItemCommand {
|
||||
adding_by: Uuid,
|
||||
|
||||
#[builder(default = "OffsetDateTime::now_utc()")]
|
||||
sale_time: OffsetDateTime,
|
||||
product_name: String,
|
||||
product_id: Uuid,
|
||||
quantity: Quantity,
|
||||
}
|
||||
|
||||
impl UnvalidatedAddLineItemCommand {
|
||||
pub fn validate(self) -> Result<AddLineItemCommand, AddLineItemCommandError> {
|
||||
let product_name = empty_string_err(
|
||||
self.product_name,
|
||||
AddLineItemCommandError::ProductNameIsEmpty,
|
||||
)?;
|
||||
|
||||
if self.quantity.is_empty() {
|
||||
return Err(AddLineItemCommandError::QuantityIsEmpty);
|
||||
}
|
||||
|
||||
Ok(AddLineItemCommand {
|
||||
sale_time: self.sale_time,
|
||||
product_name,
|
||||
product_id: self.product_id,
|
||||
quantity: self.quantity,
|
||||
adding_by: self.adding_by,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters)]
|
||||
pub struct AddLineItemCommand {
|
||||
sale_time: OffsetDateTime,
|
||||
product_name: String,
|
||||
product_id: Uuid,
|
||||
quantity: Quantity,
|
||||
|
||||
adding_by: Uuid,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::uuid::tests::UUID;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl AddLineItemCommand {
|
||||
pub fn get_cmd() -> Self {
|
||||
let product_name = "foo";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
let quantity = Quantity::get_quantity();
|
||||
|
||||
UnvalidatedAddLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmd() {
|
||||
let product_name = "foo";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
let quantity = Quantity::get_quantity();
|
||||
|
||||
let cmd = UnvalidatedAddLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(cmd.quantity(), &quantity);
|
||||
assert_eq!(*cmd.product_id(), product_id);
|
||||
assert_eq!(*cmd.adding_by(), adding_by);
|
||||
assert_eq!(cmd.product_name(), product_name);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmd_product_name_empty() {
|
||||
let product_name = "";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
let quantity = Quantity::get_quantity();
|
||||
|
||||
assert_eq!(
|
||||
UnvalidatedAddLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate(),
|
||||
Err(AddLineItemCommandError::ProductNameIsEmpty)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmd_quantity_empty() {
|
||||
let product_name = "foo";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
// minor = 0; major = 0;
|
||||
let quantity = Quantity::default();
|
||||
|
||||
assert_eq!(
|
||||
UnvalidatedAddLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate(),
|
||||
Err(AddLineItemCommandError::QuantityIsEmpty)
|
||||
);
|
||||
}
|
||||
}
|
18
src/ordering/domain/commands.rs
Normal file
18
src/ordering/domain/commands.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use mockall::predicate::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{
|
||||
add_line_item_command::AddLineItemCommand, delete_line_item::DeleteLineItemCommand,
|
||||
update_line_item_command::UpdateLineItemCommand,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum OrderingCommand {
|
||||
AddLineItem(AddLineItemCommand),
|
||||
UpdateLineItem(UpdateLineItemCommand),
|
||||
DeleteLineItem(DeleteLineItemCommand),
|
||||
}
|
37
src/ordering/domain/delete_line_item.rs
Normal file
37
src/ordering/domain/delete_line_item.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::line_item_aggregate::LineItem;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Builder, Getters,
|
||||
)]
|
||||
pub struct DeleteLineItemCommand {
|
||||
adding_by: Uuid,
|
||||
line_item: LineItem,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::uuid::tests::UUID;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl DeleteLineItemCommand {
|
||||
pub fn get_cmd() -> Self {
|
||||
let adding_by = UUID;
|
||||
|
||||
DeleteLineItemCommandBuilder::default()
|
||||
.adding_by(adding_by)
|
||||
.line_item(LineItem::get_line_item())
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
34
src/ordering/domain/events.rs
Normal file
34
src/ordering/domain/events.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use cqrs_es::DomainEvent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{
|
||||
line_item_added_event::LineItemAddedEvent, line_item_deleted_event::LineItemDeletedEvent,
|
||||
line_item_updated_event::LineItemUpdatedEvent,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum OrderingEvent {
|
||||
LineItemAdded(LineItemAddedEvent),
|
||||
LineItemUpdated(LineItemUpdatedEvent),
|
||||
LineItemDeleted(LineItemDeletedEvent),
|
||||
}
|
||||
|
||||
impl DomainEvent for OrderingEvent {
|
||||
fn event_version(&self) -> String {
|
||||
"1.0".to_string()
|
||||
}
|
||||
|
||||
fn event_type(&self) -> String {
|
||||
let e: &str = match self {
|
||||
OrderingEvent::LineItemAdded { .. } => "OrderingLineItemAdded",
|
||||
OrderingEvent::LineItemUpdated { .. } => "OrderingLineItemUpdated",
|
||||
OrderingEvent::LineItemDeleted { .. } => "OrderingLineItemDeleted",
|
||||
};
|
||||
|
||||
e.to_string()
|
||||
}
|
||||
}
|
26
src/ordering/domain/kot_aggregate.rs
Normal file
26
src/ordering/domain/kot_aggregate.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cqrs_es::Aggregate;
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::line_item_aggregate::*;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Builder, Getters,
|
||||
)]
|
||||
pub struct Kot {
|
||||
#[builder(default = "OffsetDateTime::now_utc()")]
|
||||
created_time: OffsetDateTime,
|
||||
line_items: Vec<LineItem>,
|
||||
kot_id: Uuid,
|
||||
order_id: Uuid,
|
||||
#[builder(default = "false")]
|
||||
deleted: bool,
|
||||
}
|
41
src/ordering/domain/line_item_added_event.rs
Normal file
41
src/ordering/domain/line_item_added_event.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::line_item_aggregate::LineItem;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Builder, Serialize, Deserialize, Getters, Eq, PartialEq, Ord, PartialOrd,
|
||||
)]
|
||||
pub struct LineItemAddedEvent {
|
||||
added_by_user: Uuid,
|
||||
|
||||
line_item: LineItem,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use crate::ordering::domain::add_line_item_command::AddLineItemCommand;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn get_added_line_item_event_from_command(cmd: &AddLineItemCommand) -> LineItemAddedEvent {
|
||||
let line_item = LineItem::get_line_item();
|
||||
|
||||
LineItemAddedEventBuilder::default()
|
||||
.added_by_user(cmd.adding_by().clone())
|
||||
.line_item(line_item)
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_event() {
|
||||
get_added_line_item_event_from_command(&AddLineItemCommand::get_cmd());
|
||||
}
|
||||
}
|
51
src/ordering/domain/line_item_aggregate.rs
Normal file
51
src/ordering/domain/line_item_aggregate.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cqrs_es::Aggregate;
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::types::quantity::Quantity;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Builder, Getters,
|
||||
)]
|
||||
pub struct LineItem {
|
||||
#[builder(default = "OffsetDateTime::now_utc()")]
|
||||
sale_time: OffsetDateTime,
|
||||
product_name: String,
|
||||
product_id: Uuid,
|
||||
line_item_id: Uuid,
|
||||
quantity: Quantity,
|
||||
#[builder(default = "false")]
|
||||
deleted: bool,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
ordering::domain::add_line_item_command::AddLineItemCommand, utils::uuid::tests::UUID,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
impl LineItem {
|
||||
pub fn get_line_item() -> Self {
|
||||
let cmd = AddLineItemCommand::get_cmd();
|
||||
|
||||
LineItemBuilder::default()
|
||||
.sale_time(cmd.sale_time().clone())
|
||||
.product_name("test_product".into())
|
||||
.product_id(*cmd.product_id())
|
||||
.quantity(cmd.quantity().clone())
|
||||
.line_item_id(UUID)
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
41
src/ordering/domain/line_item_deleted_event.rs
Normal file
41
src/ordering/domain/line_item_deleted_event.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::line_item_aggregate::*;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Builder, Serialize, Deserialize, Getters, Eq, PartialEq, Ord, PartialOrd,
|
||||
)]
|
||||
pub struct LineItemDeletedEvent {
|
||||
added_by_user: Uuid,
|
||||
|
||||
line_item: LineItem,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use crate::ordering::domain::delete_line_item::DeleteLineItemCommand;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn get_updated_line_item_event_from_command(
|
||||
cmd: &DeleteLineItemCommand,
|
||||
) -> LineItemDeletedEvent {
|
||||
LineItemDeletedEventBuilder::default()
|
||||
.added_by_user(cmd.adding_by().clone())
|
||||
.line_item(cmd.line_item().clone())
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_event() {
|
||||
get_updated_line_item_event_from_command(&DeleteLineItemCommand::get_cmd());
|
||||
}
|
||||
}
|
52
src/ordering/domain/line_item_updated_event.rs
Normal file
52
src/ordering/domain/line_item_updated_event.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::line_item_aggregate::*;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Builder, Serialize, Deserialize, Getters, Eq, PartialEq, Ord, PartialOrd,
|
||||
)]
|
||||
pub struct LineItemUpdatedEvent {
|
||||
added_by_user: Uuid,
|
||||
|
||||
new_line_item: LineItem,
|
||||
old_line_item: LineItem,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use crate::ordering::domain::update_line_item_command::UpdateLineItemCommand;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub fn get_updated_line_item_event_from_command(
|
||||
cmd: &UpdateLineItemCommand,
|
||||
) -> LineItemUpdatedEvent {
|
||||
let new_line_item = LineItemBuilder::default()
|
||||
.sale_time(cmd.sale_time().clone())
|
||||
.product_name(cmd.product_name().clone())
|
||||
.product_id(*cmd.product_id())
|
||||
.quantity(cmd.quantity().clone())
|
||||
.line_item_id(*cmd.old_line_item().line_item_id())
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
LineItemUpdatedEventBuilder::default()
|
||||
.added_by_user(cmd.adding_by().clone())
|
||||
.old_line_item(cmd.old_line_item().clone())
|
||||
.new_line_item(new_line_item)
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_event() {
|
||||
get_updated_line_item_event_from_command(&UpdateLineItemCommand::get_cmd());
|
||||
}
|
||||
}
|
|
@ -1,3 +1,19 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
// aggregates
|
||||
pub mod kot_aggregate;
|
||||
pub mod line_item_aggregate;
|
||||
|
||||
// commands
|
||||
pub mod add_line_item_command;
|
||||
pub mod commands;
|
||||
pub mod delete_line_item;
|
||||
pub mod update_line_item_command;
|
||||
|
||||
// events
|
||||
pub mod events;
|
||||
pub mod line_item_added_event;
|
||||
pub mod line_item_deleted_event;
|
||||
pub mod line_item_updated_event;
|
||||
|
|
166
src/ordering/domain/update_line_item_command.rs
Normal file
166
src/ordering/domain/update_line_item_command.rs
Normal file
|
@ -0,0 +1,166 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use derive_builder::Builder;
|
||||
use derive_getters::Getters;
|
||||
use derive_more::{Display, Error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::types::quantity::*;
|
||||
use crate::utils::string::empty_string_err;
|
||||
|
||||
use super::line_item_aggregate::LineItem;
|
||||
|
||||
#[derive(Debug, Error, Display, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum UpdateLineItemCommandError {
|
||||
QuantityIsEmpty,
|
||||
ProductNameIsEmpty,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||||
)]
|
||||
pub struct UnvalidatedUpdateLineItemCommand {
|
||||
adding_by: Uuid,
|
||||
|
||||
#[builder(default = "OffsetDateTime::now_utc()")]
|
||||
sale_time: OffsetDateTime,
|
||||
product_name: String,
|
||||
product_id: Uuid,
|
||||
quantity: Quantity,
|
||||
|
||||
old_line_item: LineItem,
|
||||
}
|
||||
|
||||
impl UnvalidatedUpdateLineItemCommand {
|
||||
pub fn validate(self) -> Result<UpdateLineItemCommand, UpdateLineItemCommandError> {
|
||||
let product_name = empty_string_err(
|
||||
self.product_name,
|
||||
UpdateLineItemCommandError::ProductNameIsEmpty,
|
||||
)?;
|
||||
|
||||
if self.quantity.is_empty() {
|
||||
return Err(UpdateLineItemCommandError::QuantityIsEmpty);
|
||||
}
|
||||
|
||||
Ok(UpdateLineItemCommand {
|
||||
sale_time: self.sale_time,
|
||||
product_name,
|
||||
product_id: self.product_id,
|
||||
quantity: self.quantity,
|
||||
adding_by: self.adding_by,
|
||||
old_line_item: self.old_line_item,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters)]
|
||||
pub struct UpdateLineItemCommand {
|
||||
sale_time: OffsetDateTime,
|
||||
product_name: String,
|
||||
product_id: Uuid,
|
||||
quantity: Quantity,
|
||||
|
||||
old_line_item: LineItem,
|
||||
|
||||
adding_by: Uuid,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::uuid::tests::UUID;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl UpdateLineItemCommand {
|
||||
pub fn get_cmd() -> Self {
|
||||
let product_name = "foo";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
let quantity = Quantity::get_quantity();
|
||||
|
||||
UnvalidatedUpdateLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.old_line_item(LineItem::get_line_item())
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmd() {
|
||||
let product_name = "foo";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
let quantity = Quantity::get_quantity();
|
||||
let old_line_item = LineItem::get_line_item();
|
||||
|
||||
let cmd = UnvalidatedUpdateLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.old_line_item(old_line_item.clone())
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(cmd.quantity(), &quantity);
|
||||
assert_eq!(*cmd.product_id(), product_id);
|
||||
assert_eq!(*cmd.adding_by(), adding_by);
|
||||
assert_eq!(cmd.product_name(), product_name);
|
||||
assert_eq!(cmd.old_line_item(), &old_line_item);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmd_product_name_empty() {
|
||||
let product_name = "";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
let quantity = Quantity::get_quantity();
|
||||
|
||||
assert_eq!(
|
||||
UnvalidatedUpdateLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.old_line_item(LineItem::get_line_item())
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate(),
|
||||
Err(UpdateLineItemCommandError::ProductNameIsEmpty)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmd_quantity_empty() {
|
||||
let product_name = "foo";
|
||||
let product_id = UUID;
|
||||
let adding_by = UUID;
|
||||
// minor = 0; major = 0;
|
||||
let quantity = Quantity::default();
|
||||
|
||||
assert_eq!(
|
||||
UnvalidatedUpdateLineItemCommandBuilder::default()
|
||||
.product_name(product_name.into())
|
||||
.adding_by(adding_by)
|
||||
.quantity(quantity.clone())
|
||||
.product_id(product_id)
|
||||
.old_line_item(LineItem::get_line_item())
|
||||
.build()
|
||||
.unwrap()
|
||||
.validate(),
|
||||
Err(UpdateLineItemCommandError::QuantityIsEmpty)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,4 +4,5 @@
|
|||
|
||||
pub mod parse_aggregate_id;
|
||||
pub mod random_string;
|
||||
pub mod string;
|
||||
pub mod uuid;
|
||||
|
|
61
src/utils/string.rs
Normal file
61
src/utils/string.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
// if let s: Option<String> = Some("".into()); transform to None;
|
||||
pub fn clean_option_empty_string(s: Option<String>) -> Option<String> {
|
||||
if let Some(s) = s {
|
||||
let s = s.trim();
|
||||
if s.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(s.to_owned())
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty_string_err<E: std::error::Error>(s: String, e: E) -> Result<String, E> {
|
||||
let s = s.trim().to_owned();
|
||||
if s.is_empty() {
|
||||
return Err(e);
|
||||
}
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use derive_more::{Display, Error};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_clean_option_empty_string() {
|
||||
assert!(clean_option_empty_string(Some("".into())).is_none());
|
||||
assert!(clean_option_empty_string(Some("foo".into())).is_some());
|
||||
assert_eq!(
|
||||
clean_option_empty_string(Some("foo".into())).unwrap(),
|
||||
"foo"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_string_err() {
|
||||
let s: String = "foo".into();
|
||||
|
||||
#[derive(Display, Debug, Eq, PartialEq, Error)]
|
||||
enum TestError {
|
||||
EmptyString,
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
empty_string_err(format!(" {s} "), TestError::EmptyString).unwrap(),
|
||||
s
|
||||
);
|
||||
assert_eq!(
|
||||
empty_string_err(format!(" "), TestError::EmptyString),
|
||||
Err(TestError::EmptyString)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue