feat: identity set and remove employee from roles at a store
This commit is contained in:
parent
5c649953ba
commit
c75029dd72
12 changed files with 616 additions and 17 deletions
|
@ -50,6 +50,7 @@ pub enum WebError {
|
|||
DuplicateRoleID,
|
||||
DuplicateRoleName,
|
||||
RoleIDNotFound,
|
||||
RoleNotFound,
|
||||
}
|
||||
|
||||
impl From<IdentityError> for WebError {
|
||||
|
@ -77,6 +78,7 @@ impl From<IdentityError> for WebError {
|
|||
IdentityError::DuplicateRoleID => Self::DuplicateRoleID,
|
||||
IdentityError::DuplicateRoleName => Self::DuplicateRoleName,
|
||||
IdentityError::RoleIDNotFound => Self::RoleIDNotFound,
|
||||
IdentityError::RoleNotFound => Self::RoleNotFound,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +110,7 @@ impl ResponseError for WebError {
|
|||
Self::DuplicateRoleID => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Self::DuplicateRoleName => StatusCode::BAD_REQUEST,
|
||||
Self::RoleIDNotFound => StatusCode::BAD_REQUEST,
|
||||
Self::RoleNotFound => StatusCode::NOT_FOUND,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,6 +142,7 @@ impl ResponseError for WebError {
|
|||
Self::DuplicateRoleID => HttpResponse::InternalServerError().json(e),
|
||||
Self::DuplicateRoleName => HttpResponse::BadRequest().json(e),
|
||||
Self::RoleIDNotFound => HttpResponse::BadRequest().json(e),
|
||||
Self::RoleNotFound => HttpResponse::NotFound().json(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,14 @@ impl View<Employee> for EmployeeView {
|
|||
self.store_id = None;
|
||||
self.role_id = None;
|
||||
}
|
||||
IdentityEvent::RoleAdded(e) => {
|
||||
self.store_id = Some(*e.store_id());
|
||||
self.role_id = Some(*e.role_id());
|
||||
}
|
||||
IdentityEvent::EmployeeRemovedFromRole(e) => {
|
||||
self.role_id = None;
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ pub enum IdentityError {
|
|||
DuplicateRoleID,
|
||||
DuplicateRoleName,
|
||||
RoleIDNotFound,
|
||||
RoleNotFound,
|
||||
}
|
||||
|
||||
pub type IdentityCommandResult<V> = Result<V, IdentityCommandError>;
|
||||
|
|
|
@ -12,7 +12,8 @@ use super::update_email::events::*;
|
|||
use super::update_password::events::*;
|
||||
|
||||
use crate::identity::domain::{
|
||||
employee_logged_in_event::*, employee_registered_event::*, login_otp_sent_event::*,
|
||||
employee_logged_in_event::*, employee_registered_event::*,
|
||||
employee_removed_from_role::EmployeeRemovedFromRoleEvent, login_otp_sent_event::*,
|
||||
organization_exited_event::*, owner_added_employee_to_store_event::*,
|
||||
owner_removed_employee_from_store_event::*, phone_number_changed_event::*,
|
||||
phone_number_verified_event::*, resend_login_otp_event::*, role_added_event::*,
|
||||
|
@ -33,6 +34,7 @@ pub enum IdentityEvent {
|
|||
OwnerAddedEmployeeToStore(OwnerAddedEmployeeToStoreEvent),
|
||||
OwnerRemovedEmployeeFromStore(OwnerRemovedEmployeeFromStoreEvent),
|
||||
RoleAdded(RoleAddedEvent),
|
||||
EmployeeRemovedFromRole(EmployeeRemovedFromRoleEvent),
|
||||
|
||||
// employee
|
||||
EmployeeRegistered(EmployeeRegisteredEvent),
|
||||
|
@ -73,6 +75,7 @@ impl DomainEvent for IdentityEvent {
|
|||
"IdentityOwnerRemovedEmployeeFromStore"
|
||||
}
|
||||
IdentityEvent::RoleAdded { .. } => "IdentityRoleAddedEvent",
|
||||
IdentityEvent::EmployeeRemovedFromRole { .. } => "IdentityEmployeeRemovedFromRole",
|
||||
// employee
|
||||
IdentityEvent::EmployeeRegistered { .. } => "EmployeeRegistered",
|
||||
IdentityEvent::EmployeeLoggedIn { .. } => "EmployeeLoggedIn",
|
||||
|
|
|
@ -67,6 +67,7 @@ use crate::identity::domain::{
|
|||
exit_organization_command::*,
|
||||
owner_add_employee_to_store_command::*,
|
||||
owner_remove_employee_from_store_command::*,
|
||||
remove_employee_from_role_command::*,
|
||||
resend_login_otp_command::*,
|
||||
resend_verification_otp_command::*,
|
||||
update_store_command::*,
|
||||
|
@ -113,6 +114,8 @@ pub enum IdentityCommand {
|
|||
OwnerAddEmployeeToStore(OwnerAddEmployeeToStoreCommand),
|
||||
OwnerRemoveEmployeeFromStore(OwnerRemoveEmployeeFromStoreCommand),
|
||||
AddRole(AddRoleCommand),
|
||||
RemoveEmployeeFromRole(RemoveEmployeeFromRoleCommand),
|
||||
|
||||
// employee
|
||||
EmployeeRegister(EmployeeRegisterCommand),
|
||||
EmployeeInitLogin(EmployeeInitLoginCommand),
|
||||
|
@ -327,6 +330,8 @@ impl IdentityServices {
|
|||
OwnerManageStoreEmployeesServiceBuilder::default()
|
||||
.db_store_id_exists_adapter(out_db_store_id_exists.clone())
|
||||
.db_emp_id_exists_adapter(out_db_emp_id_exists.clone())
|
||||
.db_role_id_exists_adapter(out_db_role_id_exists.clone())
|
||||
.db_role_name_exists_for_store_adapter(out_db_role_name_exists_for_store.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
);
|
||||
|
|
|
@ -5,10 +5,14 @@ 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::application::port::output::db::{
|
||||
emp_id_exists::*, role_id_exists::*, role_name_exists_for_store::*, store_id_exists::*,
|
||||
};
|
||||
use crate::identity::domain::{
|
||||
owner_add_employee_to_store_command::*, owner_added_employee_to_store_event::*,
|
||||
owner_remove_employee_from_store_command::*, owner_removed_employee_from_store_event::*,
|
||||
employee_removed_from_role::*, owner_add_employee_to_store_command::*,
|
||||
owner_added_employee_to_store_event::*, owner_remove_employee_from_store_command::*,
|
||||
owner_removed_employee_from_store_event::*, remove_employee_from_role_command::*,
|
||||
role_set_to_employee_event::*, set_role_to_employee_command::*,
|
||||
};
|
||||
|
||||
use super::errors::*;
|
||||
|
@ -24,6 +28,14 @@ pub trait OwnerManageStoreEmployeesUseCase: Send + Sync {
|
|||
&self,
|
||||
cmd: OwnerRemoveEmployeeFromStoreCommand,
|
||||
) -> IdentityResult<OwnerRemovedEmployeeFromStoreEvent>;
|
||||
async fn set_role_to_employee(
|
||||
&self,
|
||||
cmd: SetRoleToEmployeeCommand,
|
||||
) -> IdentityResult<RoleSetToEmployeeEvent>;
|
||||
async fn remove_employee_from_role(
|
||||
&self,
|
||||
cmd: RemoveEmployeeFromRoleCommand,
|
||||
) -> IdentityResult<EmployeeRemovedFromRoleEvent>;
|
||||
}
|
||||
|
||||
pub type OwnerManageStoreEmployeesServiceObj = std::sync::Arc<dyn OwnerManageStoreEmployeesUseCase>;
|
||||
|
@ -32,6 +44,8 @@ pub type OwnerManageStoreEmployeesServiceObj = std::sync::Arc<dyn OwnerManageSto
|
|||
pub struct OwnerManageStoreEmployeesService {
|
||||
db_emp_id_exists_adapter: EmpIDExistsOutDBPortObj,
|
||||
db_store_id_exists_adapter: StoreIDExistsDBPortObj,
|
||||
db_role_id_exists_adapter: RoleIDExistsDBPortObj,
|
||||
db_role_name_exists_for_store_adapter: RoleNameExistsForStoreDBPortObj,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
@ -91,11 +105,107 @@ impl OwnerManageStoreEmployeesUseCase for OwnerManageStoreEmployeesService {
|
|||
.build()
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
async fn set_role_to_employee(
|
||||
&self,
|
||||
cmd: SetRoleToEmployeeCommand,
|
||||
) -> IdentityResult<RoleSetToEmployeeEvent> {
|
||||
if !self
|
||||
.db_store_id_exists_adapter
|
||||
.store_id_exists(cmd.store_id())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::StoreNotFound);
|
||||
}
|
||||
|
||||
if !self
|
||||
.db_emp_id_exists_adapter
|
||||
.emp_id_exists(cmd.emp_id())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::EmployeeNotFound);
|
||||
}
|
||||
|
||||
if !self
|
||||
.db_role_id_exists_adapter
|
||||
.role_id_exists(cmd.role().role_id())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::RoleIDNotFound);
|
||||
}
|
||||
|
||||
if !self
|
||||
.db_role_name_exists_for_store_adapter
|
||||
.role_name_exists_for_store(cmd.role())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::RoleNotFound);
|
||||
}
|
||||
|
||||
Ok(RoleSetToEmployeeEventBuilder::default()
|
||||
.emp_id(*cmd.emp_id())
|
||||
.store_id(*cmd.store_id())
|
||||
.added_by(*cmd.adding_by())
|
||||
.role(cmd.role().clone())
|
||||
.build()
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
async fn remove_employee_from_role(
|
||||
&self,
|
||||
cmd: RemoveEmployeeFromRoleCommand,
|
||||
) -> IdentityResult<EmployeeRemovedFromRoleEvent> {
|
||||
if !self
|
||||
.db_store_id_exists_adapter
|
||||
.store_id_exists(cmd.store_id())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::StoreNotFound);
|
||||
}
|
||||
|
||||
if !self
|
||||
.db_emp_id_exists_adapter
|
||||
.emp_id_exists(cmd.employee().emp_id())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::EmployeeNotFound);
|
||||
}
|
||||
|
||||
if cmd.employee().role_id() != &Some(*cmd.role().role_id()) {
|
||||
return Err(IdentityError::RoleNotFound);
|
||||
}
|
||||
|
||||
if !self
|
||||
.db_role_id_exists_adapter
|
||||
.role_id_exists(cmd.role().role_id())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::RoleIDNotFound);
|
||||
}
|
||||
|
||||
if !self
|
||||
.db_role_name_exists_for_store_adapter
|
||||
.role_name_exists_for_store(cmd.role())
|
||||
.await?
|
||||
{
|
||||
return Err(IdentityError::RoleNotFound);
|
||||
}
|
||||
|
||||
Ok(EmployeeRemovedFromRoleEventBuilder::default()
|
||||
.emp_id(*cmd.employee().emp_id())
|
||||
.store_id(*cmd.store_id())
|
||||
.added_by(*cmd.adding_by())
|
||||
.role(cmd.role().clone())
|
||||
.build()
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{tests::bdd::*, utils::uuid::tests::*};
|
||||
use crate::{
|
||||
identity::domain::employee_aggregate::Employee, tests::bdd::*, utils::uuid::tests::*,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -125,16 +235,15 @@ mod tests {
|
|||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = OwnerAddEmployeeToStoreCommandBuilder::default()
|
||||
.emp_id(UUID)
|
||||
.store_id(UUID)
|
||||
.adding_by(UUID)
|
||||
.build()
|
||||
.unwrap();
|
||||
let cmd = OwnerAddEmployeeToStoreCommand::get_cmd();
|
||||
|
||||
let res = s.add_employee_to_store(cmd.clone()).await.unwrap();
|
||||
assert_eq!(*res.emp_id(), *cmd.emp_id());
|
||||
|
@ -148,16 +257,15 @@ mod tests {
|
|||
let s = OwnerManageStoreEmployeesServiceBuilder::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_CALLED_ONLY_ONCE))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = OwnerAddEmployeeToStoreCommandBuilder::default()
|
||||
.emp_id(UUID)
|
||||
.adding_by(UUID)
|
||||
.store_id(UUID)
|
||||
.build()
|
||||
.unwrap();
|
||||
let cmd = OwnerAddEmployeeToStoreCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.add_employee_to_store(cmd.clone()).await.err(),
|
||||
|
@ -166,11 +274,38 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_add_employee_store_no_exist() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::default()
|
||||
.db_emp_id_exists_adapter(mock_emp_id_exists_db_port(IS_NEVER_CALLED, false))
|
||||
.db_store_id_exists_adapter(mock_store_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = OwnerAddEmployeeToStoreCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.add_employee_to_store(cmd.clone()).await.err(),
|
||||
Some(IdentityError::StoreNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// remove employee
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
@ -189,6 +324,10 @@ mod tests {
|
|||
let s = OwnerManageStoreEmployeesServiceBuilder::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_CALLED_ONLY_ONCE))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
@ -201,4 +340,259 @@ mod tests {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee_store_no_exist() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::default()
|
||||
.db_emp_id_exists_adapter(mock_emp_id_exists_db_port(IS_NEVER_CALLED, true))
|
||||
.db_store_id_exists_adapter(mock_store_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = OwnerRemoveEmployeeFromStoreCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.remove_employee_from_store(cmd.clone()).await.err(),
|
||||
Some(IdentityError::StoreNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// set role to employee
|
||||
#[actix_rt::test]
|
||||
async fn test_service_set_role_to_employee() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_CALLED_ONLY_ONCE,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = SetRoleToEmployeeCommand::get_cmd();
|
||||
|
||||
let res = s.set_role_to_employee(cmd.clone()).await.unwrap();
|
||||
|
||||
assert_eq!(cmd.emp_id(), res.emp_id());
|
||||
assert_eq!(cmd.adding_by(), res.added_by());
|
||||
assert_eq!(cmd.store_id(), res.store_id());
|
||||
assert_eq!(cmd.role(), res.role());
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_set_role_to_employee_store_no_exist() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::default()
|
||||
.db_emp_id_exists_adapter(mock_emp_id_exists_db_port(IS_NEVER_CALLED, true))
|
||||
.db_store_id_exists_adapter(mock_store_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = SetRoleToEmployeeCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.set_role_to_employee(cmd.clone()).await.err(),
|
||||
Some(IdentityError::StoreNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_set_role_to_employee_role_id_no_exist() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = SetRoleToEmployeeCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.set_role_to_employee(cmd.clone()).await.err(),
|
||||
Some(IdentityError::RoleIDNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_set_role_to_employee_role_name_no_exist_for_store() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_false(
|
||||
IS_CALLED_ONLY_ONCE,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = SetRoleToEmployeeCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.set_role_to_employee(cmd.clone()).await.err(),
|
||||
Some(IdentityError::RoleNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// remove employee from role
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee_from_role() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_CALLED_ONLY_ONCE,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = RemoveEmployeeFromRoleCommand::get_cmd();
|
||||
|
||||
let res = s.remove_employee_from_role(cmd.clone()).await.unwrap();
|
||||
|
||||
assert_eq!(cmd.employee().emp_id(), res.emp_id());
|
||||
assert_eq!(cmd.adding_by(), res.added_by());
|
||||
assert_eq!(cmd.store_id(), res.store_id());
|
||||
assert_eq!(cmd.role(), res.role());
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee_from_role_no_store() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::default()
|
||||
.db_emp_id_exists_adapter(mock_emp_id_exists_db_port(IS_NEVER_CALLED, true))
|
||||
.db_store_id_exists_adapter(mock_store_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = RemoveEmployeeFromRoleCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.remove_employee_from_role(cmd.clone()).await.err(),
|
||||
Some(IdentityError::StoreNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee_from_role_no_employee() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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_CALLED_ONLY_ONCE))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = RemoveEmployeeFromRoleCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.remove_employee_from_role(cmd.clone()).await.err(),
|
||||
Some(IdentityError::EmployeeNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee_from_role_unremovable_role() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_NEVER_CALLED))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = RemoveEmployeeFromRoleCommand::get_cmd();
|
||||
let cmd = RemoveEmployeeFromRoleCommandBuilder::default()
|
||||
.role(cmd.role().clone())
|
||||
.store_id(*cmd.store_id())
|
||||
.adding_by(*cmd.adding_by())
|
||||
.employee(Employee::default())
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
s.remove_employee_from_role(cmd.clone()).await.err(),
|
||||
Some(IdentityError::RoleNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee_from_role_no_role() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_false(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_true(
|
||||
IS_NEVER_CALLED,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = RemoveEmployeeFromRoleCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.remove_employee_from_role(cmd.clone()).await.err(),
|
||||
Some(IdentityError::RoleIDNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_service_remove_employee_from_role_no_role_for_store() {
|
||||
let s = OwnerManageStoreEmployeesServiceBuilder::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))
|
||||
.db_role_id_exists_adapter(mock_role_id_exists_db_port_true(IS_CALLED_ONLY_ONCE))
|
||||
.db_role_name_exists_for_store_adapter(mock_role_name_exists_for_store_db_port_false(
|
||||
IS_CALLED_ONLY_ONCE,
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
let cmd = RemoveEmployeeFromRoleCommand::get_cmd();
|
||||
|
||||
assert_eq!(
|
||||
s.remove_employee_from_role(cmd.clone()).await.err(),
|
||||
Some(IdentityError::RoleNotFound)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,6 +171,14 @@ impl Aggregate for Employee {
|
|||
self.store_id = None;
|
||||
self.role_id = None;
|
||||
}
|
||||
IdentityEvent::RoleAdded(e) => {
|
||||
self.store_id = Some(*e.store_id());
|
||||
self.role_id = Some(*e.role_id());
|
||||
}
|
||||
IdentityEvent::EmployeeRemovedFromRole(e) => {
|
||||
self.role_id = None;
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
40
src/identity/domain/employee_removed_from_role.rs
Normal file
40
src/identity/domain/employee_removed_from_role.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
// 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::role_aggregate::*;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||||
)]
|
||||
pub struct EmployeeRemovedFromRoleEvent {
|
||||
emp_id: Uuid,
|
||||
added_by: Uuid,
|
||||
store_id: Uuid,
|
||||
role: Role,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
identity::domain::remove_employee_from_role_command::RemoveEmployeeFromRoleCommand,
|
||||
utils::uuid::tests::UUID,
|
||||
};
|
||||
|
||||
impl EmployeeRemovedFromRoleEvent {
|
||||
pub fn get_event(cmd: &RemoveEmployeeFromRoleCommand) -> Self {
|
||||
Self {
|
||||
emp_id: *cmd.employee().emp_id(),
|
||||
added_by: *cmd.adding_by(),
|
||||
store_id: *cmd.store_id(),
|
||||
role: cmd.role().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ pub mod store_aggregate;
|
|||
pub mod employee_logged_in_event;
|
||||
pub mod employee_registered_event;
|
||||
//pub mod invite_accepted_event;
|
||||
pub mod employee_removed_from_role;
|
||||
pub mod login_otp_sent_event;
|
||||
pub mod organization_exited_event;
|
||||
pub mod owner_added_employee_to_store_event;
|
||||
|
@ -21,6 +22,7 @@ pub mod phone_number_changed_event;
|
|||
pub mod phone_number_verified_event;
|
||||
pub mod resend_login_otp_event;
|
||||
pub mod role_added_event;
|
||||
pub mod role_set_to_employee_event;
|
||||
pub mod store_added_event;
|
||||
pub mod store_updated_event;
|
||||
pub mod verification_otp_resent_event;
|
||||
|
@ -36,7 +38,9 @@ pub mod employee_register_command;
|
|||
pub mod exit_organization_command;
|
||||
pub mod owner_add_employee_to_store_command;
|
||||
pub mod owner_remove_employee_from_store_command;
|
||||
pub mod remove_employee_from_role_command;
|
||||
pub mod resend_login_otp_command;
|
||||
pub mod resend_verification_otp_command;
|
||||
pub mod set_role_to_employee_command;
|
||||
pub mod update_store_command;
|
||||
pub mod verify_phone_number_command;
|
||||
|
|
53
src/identity/domain/remove_employee_from_role_command.rs
Normal file
53
src/identity/domain/remove_employee_from_role_command.rs
Normal file
|
@ -0,0 +1,53 @@
|
|||
// 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::employee_aggregate::*;
|
||||
use super::role_aggregate::Role;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||||
)]
|
||||
pub struct RemoveEmployeeFromRoleCommand {
|
||||
adding_by: Uuid,
|
||||
store_id: Uuid,
|
||||
role: Role,
|
||||
employee: Employee,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use crate::utils::uuid::tests::UUID;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl RemoveEmployeeFromRoleCommand {
|
||||
pub fn get_cmd() -> Self {
|
||||
let role = Role::default();
|
||||
let employee = Employee::default();
|
||||
let employee = EmployeeBuilder::default()
|
||||
.first_name(employee.first_name().clone())
|
||||
.last_name(employee.last_name().clone())
|
||||
.emp_id(*employee.emp_id())
|
||||
.phone_number(employee.phone_number().clone())
|
||||
.phone_verified(employee.phone_verified().clone())
|
||||
.store_id(Some(UUID))
|
||||
.deleted(false)
|
||||
.role_id(Some(*role.role_id()))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
Self {
|
||||
adding_by: UUID,
|
||||
store_id: UUID,
|
||||
role,
|
||||
employee,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
src/identity/domain/role_set_to_employee_event.rs
Normal file
40
src/identity/domain/role_set_to_employee_event.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
// 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::role_aggregate::*;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||||
)]
|
||||
pub struct RoleSetToEmployeeEvent {
|
||||
emp_id: Uuid,
|
||||
added_by: Uuid,
|
||||
store_id: Uuid,
|
||||
role: Role,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
identity::domain::set_role_to_employee_command::SetRoleToEmployeeCommand,
|
||||
utils::uuid::tests::UUID,
|
||||
};
|
||||
|
||||
impl RoleSetToEmployeeEvent {
|
||||
pub fn get_event(cmd: &SetRoleToEmployeeCommand) -> Self {
|
||||
Self {
|
||||
emp_id: *cmd.emp_id(),
|
||||
added_by: *cmd.adding_by(),
|
||||
store_id: *cmd.store_id(),
|
||||
role: cmd.role().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
src/identity/domain/set_role_to_employee_command.rs
Normal file
39
src/identity/domain/set_role_to_employee_command.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// 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::employee_aggregate::*;
|
||||
use super::role_aggregate::Role;
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Getters, Builder,
|
||||
)]
|
||||
pub struct SetRoleToEmployeeCommand {
|
||||
adding_by: Uuid,
|
||||
emp_id: Uuid,
|
||||
store_id: Uuid,
|
||||
role: Role,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use crate::utils::uuid::tests::UUID;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl SetRoleToEmployeeCommand {
|
||||
pub fn get_cmd() -> Self {
|
||||
Self {
|
||||
emp_id: UUID,
|
||||
adding_by: UUID,
|
||||
store_id: UUID,
|
||||
role: Role::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue