vanikam/src/identity/application/services/employee_exit_organization_service.rs

151 lines
4.6 KiB
Rust

// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use derive_builder::Builder;
use mockall::predicate::*;
use mockall::*;
use crate::identity::application::port::output::db::{emp_id_exists::*, store_id_exists::*};
use crate::identity::domain::{exit_organization_command::*, organization_exited_event::*};
use super::errors::*;
#[automock]
#[async_trait::async_trait]
pub trait EmployeeExitOrganizationUseCase: Send + Sync {
async fn exit_organization(
&self,
cmd: ExitOrganizationCommand,
) -> IdentityResult<OrganizationExitedEvent>;
}
pub type EmployeeExitOrganizationServiceObj = std::sync::Arc<dyn EmployeeExitOrganizationUseCase>;
#[derive(Clone, Builder)]
pub struct EmployeeExitOrganizationService {
db_emp_id_exists_adapter: EmpIDExistsOutDBPortObj,
db_store_id_exists_adapter: StoreIDExistsDBPortObj,
}
#[async_trait::async_trait]
impl EmployeeExitOrganizationUseCase for EmployeeExitOrganizationService {
async fn exit_organization(
&self,
cmd: ExitOrganizationCommand,
) -> IdentityResult<OrganizationExitedEvent> {
if !self
.db_emp_id_exists_adapter
.emp_id_exists(cmd.emp_id())
.await?
{
return Err(IdentityError::EmployeeNotFound);
}
if !self
.db_store_id_exists_adapter
.store_id_exists(cmd.emp_id())
.await?
{
return Err(IdentityError::StoreNotFound);
}
Ok(OrganizationExitedEventBuilder::default()
.emp_id(*cmd.emp_id())
.store_id(*cmd.store_id())
.build()
.unwrap())
}
}
#[cfg(test)]
mod tests {
use crate::{tests::bdd::*, utils::uuid::tests::*};
use super::*;
impl EmployeeExitOrganizationService {
pub fn mock_service(
times: Option<usize>,
cmd: ExitOrganizationCommand,
) -> EmployeeExitOrganizationServiceObj {
let res = OrganizationExitedEvent::get_event(&cmd);
let mut m = MockEmployeeExitOrganizationUseCase::default();
if let Some(times) = times {
m.expect_exit_organization()
.times(times)
.returning(move |_| Ok(res.clone()));
} else {
m.expect_exit_organization()
.returning(move |_| Ok(res.clone()));
}
std::sync::Arc::new(m)
}
}
#[actix_rt::test]
async fn test_service() {
let s = EmployeeExitOrganizationServiceBuilder::default()
.db_emp_id_exists_adapter(mock_emp_id_exists_db_port(IS_CALLED_ONLY_ONCE, true))
.db_store_id_exists_adapter(mock_store_id_exists_db_port_true(IS_CALLED_ONLY_ONCE))
.build()
.unwrap();
{
let cmd = ExitOrganizationCommandBuilder::default()
.emp_id(UUID)
.store_id(UUID)
.build()
.unwrap();
let res = s.exit_organization(cmd.clone()).await.unwrap();
assert_eq!(*res.emp_id(), UUID);
assert_eq!(*res.store_id(), UUID);
}
}
#[actix_rt::test]
async fn test_service_store_no_exist() {
let s = EmployeeExitOrganizationServiceBuilder::default()
.db_emp_id_exists_adapter(mock_emp_id_exists_db_port(IS_CALLED_ONLY_ONCE, true))
.db_store_id_exists_adapter(mock_store_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
.build()
.unwrap();
{
let cmd = ExitOrganizationCommandBuilder::default()
.emp_id(UUID)
.store_id(UUID)
.build()
.unwrap();
assert_eq!(
s.exit_organization(cmd.clone()).await.err(),
Some(IdentityError::StoreNotFound)
);
}
}
#[actix_rt::test]
async fn test_service_emp_no_exist() {
let s = EmployeeExitOrganizationServiceBuilder::default()
.db_emp_id_exists_adapter(mock_emp_id_exists_db_port(IS_CALLED_ONLY_ONCE, false))
.db_store_id_exists_adapter(mock_store_id_exists_db_port_true(IS_NEVER_CALLED))
.build()
.unwrap();
{
let cmd = ExitOrganizationCommandBuilder::default()
.emp_id(UUID)
.store_id(UUID)
.build()
.unwrap();
assert_eq!(
s.exit_organization(cmd.clone()).await.err(),
Some(IdentityError::EmployeeNotFound)
);
}
}
}