From ff6457901214384c83d2c9f9df9254211bf45a47 Mon Sep 17 00:00:00 2001 From: Julian Hyatt <54834203+julianzimmermann@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:49:21 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Feature/company=20users=20rest=20ap?= =?UTF-8?q?i=20validation=20(#81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✨add plugin execution logic before delete and update allows to execute plugins before delete and update so thats now possible to run checks for example do not let the customer deletes the own customer user or prevent the role update to remove the last admin role in the company --- composer.json | 7 +- .../CompanyUsersRestApiConstants.php | 15 +- .../CompanyUsersRestApiBusinessFactory.php | 52 +++- .../Business/CompanyUsersRestApiFacade.php | 31 +++ .../CompanyUsersRestApiFacadeInterface.php | 23 ++ .../Business/Deleter/CompanyUserDeleter.php | 13 +- .../CompanyUserPluginExecutor.php | 60 ++++- .../CompanyUserPluginExecutorInterface.php | 24 ++ .../Business/Updater/CompanyUserUpdater.php | 16 +- .../CompanyUserDeleteValidation.php | 93 +++++++ .../CompanyUserDeleteValidationInterface.php | 20 ++ .../CompanyUserUpdateValidation.php | 113 ++++++++ .../CompanyUserUpdateValidationInterface.php | 20 ++ .../DisallowSelfDeletionValidationPlugin.php | 27 ++ ...RoleProtectionOnUpdateValidationPlugin.php | 27 ++ .../CompanyUsersRestApiConfig.php | 10 +- .../CompanyUsersRestApiDependencyProvider.php | 82 ++++++ .../CompanyUsersRestApiPersistenceFactory.php | 9 + .../CompanyUsersRestApiRepository.php | 71 ++++- ...CompanyUsersRestApiRepositoryInterface.php | 27 ++ ...CompanyUsersRestApiBusinessFactoryTest.php | 12 + .../Deleter/CompanyUserDeleterTest.php | 20 ++ .../CompanyUserPluginExecutorTest.php | 85 ++++++ .../Updater/CompanyUserUpdaterTest.php | 20 ++ .../CompanyUserDeleteValidationTest.php | 243 ++++++++++++++++++ .../CompanyUserUpdateValidationTest.php | 212 +++++++++++++++ ...sallowSelfDeletionValidationPluginTest.php | 68 +++++ ...ProtectionOnUpdateValidationPluginTest.php | 68 +++++ 28 files changed, 1454 insertions(+), 14 deletions(-) create mode 100644 src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidation.php create mode 100644 src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationInterface.php create mode 100644 src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidation.php create mode 100644 src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationInterface.php create mode 100644 src/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/DisallowSelfDeletionValidationPlugin.php create mode 100644 src/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPlugin.php create mode 100644 tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationTest.php create mode 100644 tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationTest.php create mode 100644 tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/DisallowSelfDeletionValidationPluginTest.php create mode 100644 tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPluginTest.php diff --git a/composer.json b/composer.json index 7ff96af..9601fa5 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,10 @@ { "name": "Felix Pfister", "email": "felix@pfister.de" + }, + { + "name": "Julian Hyatt", + "email": "dev@jzit.de" } ], "scripts": { @@ -20,13 +24,14 @@ }, "require": { "php": ">=8.0", - "fond-of-oryx/company-users-rest-api-extension": "^1.1.0 || ^2.0.0", + "fond-of-oryx/company-users-rest-api-extension": "^2.1.0", "fond-of-spryker/company-price-list": "dev-master", "fond-of-spryker/company-user-reference": "dev-master", "spryker/company": "^1.4.0", "spryker/company-business-unit": "^1.0.0 || ^2.0.0", "spryker/company-user": "^2.3.0", "spryker/company-role": "^1.0.0", + "spryker/company-roles-rest-api": "^1.0.0", "spryker/glue-application": "^1.0.0", "spryker/permission": "^1.0.0" }, diff --git a/src/FondOfImpala/Shared/CompanyUsersRestApi/CompanyUsersRestApiConstants.php b/src/FondOfImpala/Shared/CompanyUsersRestApi/CompanyUsersRestApiConstants.php index f8f1685..d76e275 100644 --- a/src/FondOfImpala/Shared/CompanyUsersRestApi/CompanyUsersRestApiConstants.php +++ b/src/FondOfImpala/Shared/CompanyUsersRestApi/CompanyUsersRestApiConstants.php @@ -14,5 +14,18 @@ interface CompanyUsersRestApiConstants /** * @var string */ - public const BASE_URI = 'FOND_OF_SPRYKER:COMPANY_USER_REST_API:BASE_URI'; + public const BASE_URI = 'FOND_OF_IMPALA:COMPANY_USER_REST_API:BASE_URI'; + + /** + * @var string + */ + public const PROTECTED_ROLES = 'FOND_OF_IMPALA:COMPANY_USER_REST_API:PROTECTED_ROLES'; + + /** + * @var array + */ + public const PROTECTED_ROLES_DEFAULT = [ + 'super_administration', + 'administration', + ]; } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactory.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactory.php index 018a647..f17110f 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactory.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactory.php @@ -1,6 +1,6 @@ createCompanyUserReader(), $this->getCompanyUserFacade(), $this->getPermissionFacade(), + $this->createCompanyUserPluginExecutor(), ); } @@ -92,6 +97,28 @@ public function createCompanyUserWriter(): CompanyUserWriterInterface ); } + /** + * @return \FondOfImpala\Zed\CompanyUsersRestApi\Business\Validation\CompanyUserDeleteValidationInterface + */ + public function createCompanyUserDeleteValidation(): CompanyUserDeleteValidationInterface + { + return new CompanyUserDeleteValidation( + $this->getRepository(), + $this->getConfig(), + ); + } + + /** + * @return \FondOfImpala\Zed\CompanyUsersRestApi\Business\Validation\CompanyUserUpdateValidationInterface + */ + public function createCompanyUserUpdateValidation(): CompanyUserUpdateValidationInterface + { + return new CompanyUserUpdateValidation( + $this->getRepository(), + $this->getConfig(), + ); + } + /** * @return \FondOfImpala\Zed\CompanyUsersRestApi\Business\Validation\RestApiErrorInterface */ @@ -229,6 +256,8 @@ protected function createCompanyUserPluginExecutor(): CompanyUserPluginExecutorI return new CompanyUserPluginExecutor( $this->getCompanyUserPreCreatePlugins(), $this->getCompanyUserPostCreatePlugins(), + $this->getCompanyUserPreDeleteValidationPlugins(), + $this->getCompanyUserPreUpdateValidationPlugins(), ); } @@ -242,6 +271,26 @@ protected function getCompanyUserPostCreatePlugins(): array ); } + /** + * @return array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreDeleteValidationPluginInterface> + */ + protected function getCompanyUserPreDeleteValidationPlugins(): array + { + return $this->getProvidedDependency( + CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_DELETE_VALIDATION, + ); + } + + /** + * @return array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreUpdateValidationPluginInterface> + */ + protected function getCompanyUserPreUpdateValidationPlugins(): array + { + return $this->getProvidedDependency( + CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_UPDATE_VALIDATION, + ); + } + /** * @return array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreCreatePluginInterface> */ @@ -262,6 +311,7 @@ public function createCompanyUserUpdater(): CompanyUserUpdaterInterface $this->createCompanyRoleCollectionReader(), $this->getCompanyUserFacade(), $this->getPermissionFacade(), + $this->createCompanyUserPluginExecutor(), ); } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacade.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacade.php index 02e2c8a..5c192ac 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacade.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacade.php @@ -4,6 +4,7 @@ namespace FondOfImpala\Zed\CompanyUsersRestApi\Business; +use Generated\Shared\Transfer\CompanyUserTransfer; use Generated\Shared\Transfer\RestCompanyUsersRequestAttributesTransfer; use Generated\Shared\Transfer\RestCompanyUsersResponseTransfer; use Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer; @@ -56,4 +57,34 @@ public function updateCompanyUserByRestWriteCompanyUserRequest( ->createCompanyUserUpdater() ->updateByRestWriteCompanyUserRequest($restWriteCompanyUserRequestTransfer); } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + * + * @return bool + */ + public function canDeleteCompanyUser( + CompanyUserTransfer $companyUserTransfer, + RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + ): bool { + return $this->getFactory() + ->createCompanyUserDeleteValidation() + ->validate($companyUserTransfer, $restDeleteCompanyUserRequestTransfer); + } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + * + * @return bool + */ + public function canUpdateCompanyUser( + CompanyUserTransfer $companyUserTransfer, + RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + ): bool { + return $this->getFactory() + ->createCompanyUserUpdateValidation() + ->validate($companyUserTransfer, $restWriteCompanyUserRequestTransfer); + } } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacadeInterface.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacadeInterface.php index 2b9d9f5..76e81c3 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacadeInterface.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiFacadeInterface.php @@ -4,6 +4,7 @@ namespace FondOfImpala\Zed\CompanyUsersRestApi\Business; +use Generated\Shared\Transfer\CompanyUserTransfer; use Generated\Shared\Transfer\RestCompanyUsersRequestAttributesTransfer; use Generated\Shared\Transfer\RestCompanyUsersResponseTransfer; use Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer; @@ -39,4 +40,26 @@ public function deleteCompanyUserByRestDeleteCompanyUserRequest( public function updateCompanyUserByRestWriteCompanyUserRequest( RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer ): RestWriteCompanyUserResponseTransfer; + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + * + * @return bool + */ + public function canDeleteCompanyUser( + CompanyUserTransfer $companyUserTransfer, + RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + ): bool; + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + * + * @return bool + */ + public function canUpdateCompanyUser( + CompanyUserTransfer $companyUserTransfer, + RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + ): bool; } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleter.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleter.php index 9e128fc..86043dd 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleter.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleter.php @@ -2,6 +2,7 @@ namespace FondOfImpala\Zed\CompanyUsersRestApi\Business\Deleter; +use FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyUserReaderInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Communication\Plugin\PermissionExtension\DeleteCompanyUserPermissionPlugin; use FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToCompanyUserFacadeInterface; @@ -26,19 +27,27 @@ class CompanyUserDeleter implements CompanyUserDeleterInterface */ protected $permissionFacade; + /** + * @var \FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface + */ + protected $pluginExecutor; + /** * @param \FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyUserReaderInterface $companyUserReader * @param \FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToCompanyUserFacadeInterface $companyUserFacade * @param \FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToPermissionFacadeInterface $permissionFacade + * @param \FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface $pluginExecutor */ public function __construct( CompanyUserReaderInterface $companyUserReader, CompanyUsersRestApiToCompanyUserFacadeInterface $companyUserFacade, - CompanyUsersRestApiToPermissionFacadeInterface $permissionFacade + CompanyUsersRestApiToPermissionFacadeInterface $permissionFacade, + CompanyUserPluginExecutorInterface $pluginExecutor ) { $this->companyUserReader = $companyUserReader; $this->companyUserFacade = $companyUserFacade; $this->permissionFacade = $permissionFacade; + $this->pluginExecutor = $pluginExecutor; } /** @@ -67,7 +76,7 @@ public function deleteByRestDeleteCompanyUserRequest( $restDeleteCompanyUserRequestTransfer, ); - if ($companyUserTransfer === null) { + if ($companyUserTransfer === null || $this->pluginExecutor->executePreDeleteValidationPlugins($companyUserTransfer, $restDeleteCompanyUserRequestTransfer) === false) { return $restDeleteCompanyUserResponseTransfer; } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutor.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutor.php index f02e6f2..4b81d7b 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutor.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutor.php @@ -4,6 +4,8 @@ use Generated\Shared\Transfer\CompanyUserTransfer; use Generated\Shared\Transfer\RestCompanyUsersRequestAttributesTransfer; +use Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer; +use Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer; class CompanyUserPluginExecutor implements CompanyUserPluginExecutorInterface { @@ -17,16 +19,32 @@ class CompanyUserPluginExecutor implements CompanyUserPluginExecutorInterface */ protected $companyUserPreCreatePlugins; + /** + * @var array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreDeleteValidationPluginInterface> + */ + protected $companyUserPreDeletePlugins; + + /** + * @var array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreUpdateValidationPluginInterface> + */ + protected $companyUserPreUpdatePlugins; + /** * @param array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreCreatePluginInterface> $companyUserPreCreatePlugins * @param array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPostCreatePluginInterface> $companyUserPostCreatePlugins + * @param array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreDeleteValidationPluginInterface> $companyUserPreDeletePlugins + * @param array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreUpdateValidationPluginInterface> $companyUserPreUpdatePlugins */ public function __construct( array $companyUserPreCreatePlugins, - array $companyUserPostCreatePlugins + array $companyUserPostCreatePlugins, + array $companyUserPreDeletePlugins, + array $companyUserPreUpdatePlugins ) { $this->companyUserPreCreatePlugins = $companyUserPreCreatePlugins; $this->companyUserPostCreatePlugins = $companyUserPostCreatePlugins; + $this->companyUserPreDeletePlugins = $companyUserPreDeletePlugins; + $this->companyUserPreUpdatePlugins = $companyUserPreUpdatePlugins; } /** @@ -62,4 +80,44 @@ public function executePreCreatePlugins( return $companyUserTransfer; } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + * + * @return bool + */ + public function executePreDeleteValidationPlugins( + CompanyUserTransfer $companyUserTransfer, + RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + ): bool { + foreach ($this->companyUserPreDeletePlugins as $plugin) { + $state = $plugin->validate($companyUserTransfer, $restDeleteCompanyUserRequestTransfer); + if ($state === false) { + return false; + } + } + + return true; + } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + * + * @return bool + */ + public function executePreUpdateValidationPlugins( + CompanyUserTransfer $companyUserTransfer, + RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + ): bool { + foreach ($this->companyUserPreUpdatePlugins as $plugin) { + $state = $plugin->validate($companyUserTransfer, $restWriteCompanyUserRequestTransfer); + if ($state === false) { + return false; + } + } + + return true; + } } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorInterface.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorInterface.php index 22315d1..b46079f 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorInterface.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorInterface.php @@ -4,6 +4,8 @@ use Generated\Shared\Transfer\CompanyUserTransfer; use Generated\Shared\Transfer\RestCompanyUsersRequestAttributesTransfer; +use Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer; +use Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer; interface CompanyUserPluginExecutorInterface { @@ -28,4 +30,26 @@ public function executePreCreatePlugins( CompanyUserTransfer $companyUserTransfer, RestCompanyUsersRequestAttributesTransfer $companyUsersRequestAttributesTransfer ): CompanyUserTransfer; + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + * + * @return bool + */ + public function executePreDeleteValidationPlugins( + CompanyUserTransfer $companyUserTransfer, + RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + ): bool; + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + * + * @return bool + */ + public function executePreUpdateValidationPlugins( + CompanyUserTransfer $companyUserTransfer, + RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + ): bool; } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdater.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdater.php index 2e7c369..f004b5f 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdater.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdater.php @@ -2,6 +2,7 @@ namespace FondOfImpala\Zed\CompanyUsersRestApi\Business\Updater; +use FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyRoleCollectionReaderInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyUserReaderInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Communication\Plugin\PermissionExtension\UpdateCompanyUserPermissionPlugin; @@ -33,22 +34,30 @@ class CompanyUserUpdater implements CompanyUserUpdaterInterface */ protected $permissionFacade; + /** + * @var \FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface + */ + protected $pluginExecutor; + /** * @param \FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyUserReaderInterface $companyUserReader * @param \FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyRoleCollectionReaderInterface $companyRoleCollectionReader * @param \FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToCompanyUserFacadeInterface $companyUserFacade * @param \FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToPermissionFacadeInterface $permissionFacade + * @param \FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface $pluginExecutor */ public function __construct( CompanyUserReaderInterface $companyUserReader, CompanyRoleCollectionReaderInterface $companyRoleCollectionReader, CompanyUsersRestApiToCompanyUserFacadeInterface $companyUserFacade, - CompanyUsersRestApiToPermissionFacadeInterface $permissionFacade + CompanyUsersRestApiToPermissionFacadeInterface $permissionFacade, + CompanyUserPluginExecutorInterface $pluginExecutor ) { $this->companyUserReader = $companyUserReader; $this->companyRoleCollectionReader = $companyRoleCollectionReader; $this->companyUserFacade = $companyUserFacade; $this->permissionFacade = $permissionFacade; + $this->pluginExecutor = $pluginExecutor; } /** @@ -89,6 +98,11 @@ public function updateByRestWriteCompanyUserRequest( $companyUserTransfer = $companyUserTransfer->setCustomer( (new CustomerTransfer())->setIdCustomer($companyUserTransfer->getFkCustomer()), ); + + if (!$this->pluginExecutor->executePreUpdateValidationPlugins($companyUserTransfer, $restWriteCompanyUserRequestTransfer)) { + return $restWriteCompanyUserResponseTransfer; + } + $companyUserResponseTransfer = $this->companyUserFacade->update($companyUserTransfer); $companyUserTransfer = $companyUserResponseTransfer->getCompanyUser(); diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidation.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidation.php new file mode 100644 index 0000000..27b3d98 --- /dev/null +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidation.php @@ -0,0 +1,93 @@ +repository = $repository; + $this->config = $config; + } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + * + * @return bool + */ + public function validate( + CompanyUserTransfer $companyUserTransfer, + RestDeleteCompanyUserRequestTransfer $restDeleteCompanyUserRequestTransfer + ): bool { + $companyUserCollection = $this->repository->findCompanyUserByFkCompany($companyUserTransfer->getFkCompany()); + + if (count($companyUserCollection->getCompanyUsers()) <= 1 || $this->isProtectedByRole($companyUserTransfer)) { + return false; + } + + $loggedInCompanyUserTransfer = $this->resolveLoggedInCompanyUser($companyUserCollection, $restDeleteCompanyUserRequestTransfer->getIdCustomer()); + + return $loggedInCompanyUserTransfer !== null && $companyUserTransfer->getFkCustomer() !== $loggedInCompanyUserTransfer->getFkCustomer(); + } + + /** + * @param \Generated\Shared\Transfer\CompanyUserCollectionTransfer $companyUserCollectionTransfer + * @param int $idCustomer + * + * @return \Generated\Shared\Transfer\CompanyUserTransfer|null + */ + protected function resolveLoggedInCompanyUser(CompanyUserCollectionTransfer $companyUserCollectionTransfer, int $idCustomer): ?CompanyUserTransfer + { + foreach ($companyUserCollectionTransfer->getCompanyUsers() as $companyUserTransfer) { + if ($companyUserTransfer->getFkCustomer() === $idCustomer) { + return $companyUserTransfer; + } + } + + return null; + } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * + * @return bool + */ + protected function isProtectedByRole(CompanyUserTransfer $companyUserTransfer): bool + { + $protectedRoles = $this->config->getProtectedRoles(); + + if (count($protectedRoles) === 0) { + return false; + } + + $userRoles = $this->repository->findCompanyUserRolesByCompanyUser($companyUserTransfer); + foreach ($userRoles as $userRole) { + if (in_array($userRole, $protectedRoles, true)) { + return true; + } + } + + return false; + } +} diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationInterface.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationInterface.php new file mode 100644 index 0000000..518e02c --- /dev/null +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationInterface.php @@ -0,0 +1,20 @@ +repository = $repository; + $this->config = $config; + } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * @param \Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + * + * @return bool + */ + public function validate( + CompanyUserTransfer $companyUserTransfer, + RestWriteCompanyUserRequestTransfer $restWriteCompanyUserRequestTransfer + ): bool { + $companyUserCollection = $this->repository->findCompanyUserByFkCompany($companyUserTransfer->getFkCompany()); + + if (count($companyUserCollection->getCompanyUsers()) <= 1) { + return false; + } + + $roleData = $this->repository->findCompanyUserRolesByFkCompany($companyUserTransfer->getFkCompany()); + $resolvedRoleCounts = $this->getProtectedRoleCountUsage($roleData); + $roleBeforeUpdate = $this->getCurrentRole($companyUserTransfer->getIdCompanyUser(), $roleData); + + if (array_key_exists($roleBeforeUpdate, $resolvedRoleCounts) && $resolvedRoleCounts[$roleBeforeUpdate] <= 1) { + return false; + } + + return true; + } + + /** + * @param int $idCompanyUser + * @param array> $roleData + * + * @throws \Exception + * + * @return string + */ + protected function getCurrentRole(int $idCompanyUser, array $roleData): string + { + foreach ($roleData as $data) { + if (!array_key_exists(SpyCompanyRoleToCompanyUserTableMap::COL_FK_COMPANY_USER, $data) || $data[SpyCompanyRoleToCompanyUserTableMap::COL_FK_COMPANY_USER] !== $idCompanyUser) { + continue; + } + + return $data[SpyCompanyRoleTableMap::COL_NAME]; + } + + throw new Exception(sprintf('Could not resolve role before update of company user with id "%s"', $idCompanyUser)); + } + + /** + * @param array> $roles + * + * @return array + */ + protected function getProtectedRoleCountUsage(array $roles): array + { + $protectedRoles = $this->config->getProtectedRoles(); + $counts = []; + + if (count($protectedRoles) === 0) { + return $counts; + } + + foreach ($roles as $role) { + if (!in_array($role[SpyCompanyRoleTableMap::COL_NAME], $protectedRoles, true)) { + continue; + } + $role = $role[SpyCompanyRoleTableMap::COL_NAME]; + if (array_key_exists($role, $counts)) { + $counts[$role] += 1; + + continue; + } + + $counts[$role] = 1; + } + + return $counts; + } +} diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationInterface.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationInterface.php new file mode 100644 index 0000000..8b607b5 --- /dev/null +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationInterface.php @@ -0,0 +1,20 @@ +getFacade()->canDeleteCompanyUser($companyUserTransfer, $restDeleteCompanyUserRequestTransfer); + } +} diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPlugin.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPlugin.php new file mode 100644 index 0000000..422d583 --- /dev/null +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPlugin.php @@ -0,0 +1,27 @@ +getFacade()->canUpdateCompanyUser($companyUserTransfer, $restWriteCompanyUserRequestTransfer); + } +} diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiConfig.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiConfig.php index 50afa41..c5f10c1 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiConfig.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiConfig.php @@ -1,6 +1,6 @@ get(CompanyUsersRestApiConstants::BASE_URI, 'http://127.0.0.1/'); } + + /** + * @return array + */ + public function getProtectedRoles(): array + { + return $this->get(CompanyUsersRestApiConstants::PROTECTED_ROLES, CompanyUsersRestApiConstants::PROTECTED_ROLES_DEFAULT); + } } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiDependencyProvider.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiDependencyProvider.php index 2182106..741e7f6 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiDependencyProvider.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/CompanyUsersRestApiDependencyProvider.php @@ -12,6 +12,7 @@ use FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToCustomerFacadeBridge; use FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToPermissionFacadeBridge; use FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Service\CompanyUsersRestApiToUtilTextServiceBridge; +use Orm\Zed\CompanyRole\Persistence\SpyCompanyRoleToCompanyUserQuery; use Orm\Zed\CompanyUser\Persistence\SpyCompanyUserQuery; use Spryker\Zed\Kernel\AbstractBundleDependencyProvider; use Spryker\Zed\Kernel\Container; @@ -61,6 +62,11 @@ class CompanyUsersRestApiDependencyProvider extends AbstractBundleDependencyProv */ public const PROPEL_QUERY_COMPANY_USER = 'PROPEL_QUERY_COMPANY_USER'; + /** + * @var string + */ + public const PROPEL_QUERY_COMPANY_ROLE_TO_COMPANY_USER = 'PROPEL_QUERY_COMPANY_ROLE_TO_COMPANY_USER'; + /** * @var string */ @@ -71,6 +77,16 @@ class CompanyUsersRestApiDependencyProvider extends AbstractBundleDependencyProv */ public const PLUGINS_COMPANY_USER_POST_CREATE = 'PLUGINS_COMPANY_USER_POST_CREATE'; + /** + * @var string + */ + public const PLUGINS_COMPANY_USER_PRE_DELETE_VALIDATION = 'PLUGINS_COMPANY_USER_PRE_DELETE_VALIDATION'; + + /** + * @var string + */ + public const PLUGINS_COMPANY_USER_PRE_UPDATE_VALIDATION = 'PLUGINS_COMPANY_USER_PRE_UPDATE_VALIDATION'; + /** * @var string */ @@ -94,6 +110,8 @@ public function provideBusinessLayerDependencies(Container $container): Containe $container = $this->addUtilTextService($container); $container = $this->addPermissionFacade($container); $container = $this->addCompanyUserPostCreatePlugin($container); + $container = $this->addCompanyUserPreDeleteValidationPlugin($container); + $container = $this->addCompanyUserPreUpdateValidationPlugin($container); return $this->addCompanyUserPreCreatePlugins($container); } @@ -107,6 +125,8 @@ public function providePersistenceLayerDependencies(Container $container): Conta { $container = parent::providePersistenceLayerDependencies($container); + $container = $this->addCompanyRoleToCompanyUserPropelQuery($container); + return $this->addCompanyUserPropelQuery($container); } @@ -124,6 +144,20 @@ protected function addCompanyUserPropelQuery(Container $container): Container return $container; } + /** + * @param \Spryker\Zed\Kernel\Container $container + * + * @return \Spryker\Zed\Kernel\Container + */ + protected function addCompanyRoleToCompanyUserPropelQuery(Container $container): Container + { + $container[static::PROPEL_QUERY_COMPANY_ROLE_TO_COMPANY_USER] = static function () { + return SpyCompanyRoleToCompanyUserQuery::create(); + }; + + return $container; + } + /** * @param \Spryker\Zed\Kernel\Container $container * @@ -276,6 +310,54 @@ protected function getCompanyUserPostCreatePlugins(): array return []; } + /** + * @param \Spryker\Zed\Kernel\Container $container + * + * @return \Spryker\Zed\Kernel\Container + */ + public function addCompanyUserPreDeleteValidationPlugin(Container $container): Container + { + $self = $this; + + $container[static::PLUGINS_COMPANY_USER_PRE_DELETE_VALIDATION] = static function () use ($self) { + return $self->getCompanyUserPreDeleteValidationPlugins(); + }; + + return $container; + } + + /** + * @return array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreDeleteValidationPluginInterface> + */ + protected function getCompanyUserPreDeleteValidationPlugins(): array + { + return []; + } + + /** + * @param \Spryker\Zed\Kernel\Container $container + * + * @return \Spryker\Zed\Kernel\Container + */ + public function addCompanyUserPreUpdateValidationPlugin(Container $container): Container + { + $self = $this; + + $container[static::PLUGINS_COMPANY_USER_PRE_UPDATE_VALIDATION] = static function () use ($self) { + return $self->getCompanyUserPreUpdateValidationPlugins(); + }; + + return $container; + } + + /** + * @return array<\FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreUpdateValidationPluginInterface> + */ + protected function getCompanyUserPreUpdateValidationPlugins(): array + { + return []; + } + /** * @param \Spryker\Zed\Kernel\Container $container * diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiPersistenceFactory.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiPersistenceFactory.php index 2df1dbb..3ac153e 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiPersistenceFactory.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiPersistenceFactory.php @@ -7,6 +7,7 @@ use FondOfImpala\Zed\CompanyUsersRestApi\CompanyUsersRestApiDependencyProvider; use FondOfImpala\Zed\CompanyUsersRestApi\Persistence\Mapper\CompanyUserMapper; use FondOfImpala\Zed\CompanyUsersRestApi\Persistence\Mapper\CompanyUserMapperInterface; +use Orm\Zed\CompanyRole\Persistence\SpyCompanyRoleToCompanyUserQuery; use Orm\Zed\CompanyUser\Persistence\SpyCompanyUserQuery; use Spryker\Zed\Kernel\Persistence\AbstractPersistenceFactory; @@ -26,6 +27,14 @@ public function getCompanyUserPropelQuery(): SpyCompanyUserQuery return $this->getProvidedDependency(CompanyUsersRestApiDependencyProvider::PROPEL_QUERY_COMPANY_USER); } + /** + * @return \Orm\Zed\CompanyRole\Persistence\SpyCompanyRoleToCompanyUserQuery + */ + public function getCompanyRoleToCompanyUserPropelQuery(): SpyCompanyRoleToCompanyUserQuery + { + return $this->getProvidedDependency(CompanyUsersRestApiDependencyProvider::PROPEL_QUERY_COMPANY_ROLE_TO_COMPANY_USER); + } + /** * @return \FondOfImpala\Zed\CompanyUsersRestApi\Persistence\Mapper\CompanyUserMapperInterface */ diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepository.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepository.php index e31fda1..f21640d 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepository.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepository.php @@ -1,6 +1,6 @@ getFactory() ->getCompanyUserPropelQuery() ->useCustomerQuery() - ->filterByCustomerReference($customerReference) + ->filterByCustomerReference($customerReference) ->endUse() ->useCompanyQuery() - ->usePriceListQuery() - ->endUse() + ->usePriceListQuery() + ->endUse() ->endUse() ->useCompanyBusinessUnitQuery() ->endUse() ->useSpyCompanyRoleToCompanyUserQuery() - ->useCompanyRoleQuery() - ->endUse() + ->useCompanyRoleQuery() + ->endUse() ->endUse() ->find(); @@ -164,4 +166,61 @@ public function findCompanyUserByIdCustomerAndForeignCompanyUserReference( ->createCompanyUserMapper() ->mapEntityToTransfer($companyUser); } + + /** + * @param int $idCompany + * + * @return \Generated\Shared\Transfer\CompanyUserCollectionTransfer + */ + public function findCompanyUserByFkCompany( + int $idCompany + ): CompanyUserCollectionTransfer { + $collection = new CompanyUserCollectionTransfer(); + + $result = $this->getFactory() + ->getCompanyUserPropelQuery() + ->clear() + ->filterByFkCompany($idCompany) + ->find(); + + foreach ($result->getData() as $companyUser) { + $collection->addCompanyUser($this->getFactory() + ->createCompanyUserMapper() + ->mapEntityToTransfer($companyUser)); + } + + return $collection; + } + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * + * @return array + */ + public function findCompanyUserRolesByCompanyUser( + CompanyUserTransfer $companyUserTransfer + ): array { + return $this->getFactory() + ->getCompanyRoleToCompanyUserPropelQuery() + ->clear() + ->filterByFkCompanyUser($companyUserTransfer->getIdCompanyUser()) + ->useCompanyRoleQuery()->endUse() + ->select([SpyCompanyRoleTableMap::COL_NAME]) + ->find()->getData(); + } + + /** + * @param int $idCompany + * + * @return array + */ + public function findCompanyUserRolesByFkCompany(int $idCompany): array + { + return $this->getFactory() + ->getCompanyRoleToCompanyUserPropelQuery() + ->clear() + ->useCompanyRoleQuery()->filterByFkCompany($idCompany)->endUse() + ->select([SpyCompanyRoleToCompanyUserTableMap::COL_FK_COMPANY_USER, SpyCompanyRoleTableMap::COL_UUID, SpyCompanyRoleTableMap::COL_NAME]) + ->find()->getData(); + } } diff --git a/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepositoryInterface.php b/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepositoryInterface.php index 9eaa646..e3dfaf5 100644 --- a/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepositoryInterface.php +++ b/src/FondOfImpala/Zed/CompanyUsersRestApi/Persistence/CompanyUsersRestApiRepositoryInterface.php @@ -36,4 +36,31 @@ public function findCompanyUserByIdCustomerAndForeignCompanyUserReference( int $idCustomer, string $foreignCompanyUserReference ): ?CompanyUserTransfer; + + /** + * @param int $idCompany + * + * @throws \Spryker\Zed\Propel\Business\Exception\AmbiguousComparisonException + * + * @return \Generated\Shared\Transfer\CompanyUserCollectionTransfer + */ + public function findCompanyUserByFkCompany( + int $idCompany + ): CompanyUserCollectionTransfer; + + /** + * @param \Generated\Shared\Transfer\CompanyUserTransfer $companyUserTransfer + * + * @return array + */ + public function findCompanyUserRolesByCompanyUser( + CompanyUserTransfer $companyUserTransfer + ): array; + + /** + * @param int $idCompany + * + * @return array + */ + public function findCompanyUserRolesByFkCompany(int $idCompany): array; } diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactoryTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactoryTest.php index 4aa70bf..ef44012 100644 --- a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactoryTest.php +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/CompanyUsersRestApiBusinessFactoryTest.php @@ -192,6 +192,8 @@ public function testCreateCompanyUserWriter(): void [CompanyUsersRestApiDependencyProvider::FACADE_PERMISSION], [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_CREATE], [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_POST_CREATE], + [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_DELETE_VALIDATION], + [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_UPDATE_VALIDATION], )->willReturnOnConsecutiveCalls( $this->customerFacadeMock, $this->utilTextServiceMock, @@ -204,6 +206,8 @@ public function testCreateCompanyUserWriter(): void $this->permissionFacadeMock, [], [], + [], + [], ); static::assertInstanceOf( @@ -228,11 +232,19 @@ public function testCreateCompanyUserUpdater(): void [CompanyUsersRestApiDependencyProvider::FACADE_COMPANY_ROLE], [CompanyUsersRestApiDependencyProvider::FACADE_COMPANY_USER], [CompanyUsersRestApiDependencyProvider::FACADE_PERMISSION], + [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_CREATE], + [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_POST_CREATE], + [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_DELETE_VALIDATION], + [CompanyUsersRestApiDependencyProvider::PLUGINS_COMPANY_USER_PRE_UPDATE_VALIDATION], )->willReturnOnConsecutiveCalls( $this->companyUserReferenceFacadeMock, $this->companyRoleFacadeMock, $this->companyUserFacadeMock, $this->permissionFacadeMock, + [], + [], + [], + [], ); static::assertInstanceOf( diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleterTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleterTest.php index 1eca038..6f4d326 100644 --- a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleterTest.php +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Deleter/CompanyUserDeleterTest.php @@ -3,6 +3,7 @@ namespace FondOfImpala\Zed\CompanyUsersRestApi\Business\Deleter; use Codeception\Test\Unit; +use FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyUserReaderInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Communication\Plugin\PermissionExtension\DeleteCompanyUserPermissionPlugin; use FondOfImpala\Zed\CompanyUsersRestApi\Dependency\Facade\CompanyUsersRestApiToCompanyUserFacadeInterface; @@ -10,6 +11,7 @@ use Generated\Shared\Transfer\CompanyUserResponseTransfer; use Generated\Shared\Transfer\CompanyUserTransfer; use Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer; +use PHPUnit\Framework\MockObject\MockObject; class CompanyUserDeleterTest extends Unit { @@ -28,6 +30,11 @@ class CompanyUserDeleterTest extends Unit */ protected $permissionFacadeMock; + /** + * @var \FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected CompanyUserPluginExecutorInterface|MockObject $pluginExecutorMock; + /** * @var \Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer|\PHPUnit\Framework\MockObject\MockObject */ @@ -79,10 +86,15 @@ protected function _before(): void ->disableOriginalConstructor() ->getMock(); + $this->pluginExecutorMock = $this->getMockBuilder(CompanyUserPluginExecutorInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->companyUserDeleter = new CompanyUserDeleter( $this->companyUserReaderMock, $this->companyUserFacadeMock, $this->permissionFacadeMock, + $this->pluginExecutorMock, ); } @@ -122,6 +134,10 @@ public function testDeleteByRestDeleteCompanyUserRequest(): void ->method('getIsSuccessful') ->willReturn(true); + $this->pluginExecutorMock->expects(static::atLeastOnce()) + ->method('executePreDeleteValidationPlugins') + ->willReturn(true); + $restDeleteCompanyUserResponseTransfer = $this->companyUserDeleter->deleteByRestDeleteCompanyUserRequest( $this->restDeleteCompanyUserRequestTransferMock, ); @@ -237,6 +253,10 @@ public function testDeleteByRestDeleteCompanyUserRequestWithDeletionError(): voi ->method('getIsSuccessful') ->willReturn(false); + $this->pluginExecutorMock->expects(static::atLeastOnce()) + ->method('executePreDeleteValidationPlugins') + ->willReturn(true); + $restDeleteCompanyUserResponseTransfer = $this->companyUserDeleter->deleteByRestDeleteCompanyUserRequest( $this->restDeleteCompanyUserRequestTransferMock, ); diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorTest.php index 5cb95dd..c2070fc 100644 --- a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorTest.php +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/PluginExecutor/CompanyUserPluginExecutorTest.php @@ -6,8 +6,13 @@ use FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutor; use FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPostCreatePluginInterface; use FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreCreatePluginInterface; +use FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreDeleteValidationPluginInterface; +use FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreUpdateValidationPluginInterface; use Generated\Shared\Transfer\CompanyUserTransfer; use Generated\Shared\Transfer\RestCompanyUsersRequestAttributesTransfer; +use Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer; +use Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer; +use PHPUnit\Framework\MockObject\MockObject; class CompanyUserPluginExecutorTest extends Unit { @@ -16,11 +21,41 @@ class CompanyUserPluginExecutorTest extends Unit */ protected $companyUserTransferMock; + /** + * @var \FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreCreatePluginInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected CompanyUserPreCreatePluginInterface|MockObject $companyUserPreCreatePluginMock; + + /** + * @var \FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPostCreatePluginInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected CompanyUserPostCreatePluginInterface|MockObject $companyUserPostCreatePluginMock; + + /** + * @var \FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreDeleteValidationPluginInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected CompanyUserPreDeleteValidationPluginInterface|MockObject $companyUserPreDeleteValidationPluginMock; + + /** + * @var \FondOfOryx\Zed\CompanyUsersRestApiExtension\Dependency\Plugin\CompanyUserPreUpdateValidationPluginInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected CompanyUserPreUpdateValidationPluginInterface|MockObject $companyUserPreUpdateValidationPluginMock; + /** * @var \Generated\Shared\Transfer\RestCompanyUsersRequestAttributesTransfer|\PHPUnit\Framework\MockObject\MockObject */ protected $companyUsersRequestAttributesTransferMock; + /** + * @var \Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer|\PHPUnit\Framework\MockObject\MockObject + */ + protected RestWriteCompanyUserRequestTransfer|MockObject $restWriteCompanyUserRequestTransferMock; + + /** + * @var \Generated\Shared\Transfer\RestDeleteCompanyUserRequestTransfer|\PHPUnit\Framework\MockObject\MockObject + */ + protected RestDeleteCompanyUserRequestTransfer|MockObject $restDeleteCompanyUserRequestTransfer; + /** * @var \FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface */ @@ -41,6 +76,14 @@ protected function _before(): void ->disableOriginalConstructor() ->getMock(); + $this->companyUserPreDeleteValidationPluginMock = $this->getMockBuilder(CompanyUserPreDeleteValidationPluginInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserPreUpdateValidationPluginMock = $this->getMockBuilder(CompanyUserPreUpdateValidationPluginInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->companyUserTransferMock = $this->getMockBuilder(CompanyUserTransfer::class) ->disableOriginalConstructor() ->getMock(); @@ -49,9 +92,19 @@ protected function _before(): void ->disableOriginalConstructor() ->getMock(); + $this->restWriteCompanyUserRequestTransferMock = $this->getMockBuilder(RestWriteCompanyUserRequestTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->restDeleteCompanyUserRequestTransfer = $this->getMockBuilder(RestDeleteCompanyUserRequestTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + $this->pluginExecutor = new CompanyUserPluginExecutor( [$this->companyUserPreCreatePluginMock], [$this->companyUserPostCreatePluginMock], + [$this->companyUserPreDeleteValidationPluginMock], + [$this->companyUserPreUpdateValidationPluginMock], ); } @@ -92,4 +145,36 @@ public function testExecutePreCreatePlugins(): void ), ); } + + /** + * @return void + */ + public function testExecutePreUpdatePlugins(): void + { + $this->companyUserPreUpdateValidationPluginMock->expects(static::atLeastOnce()) + ->method('validate') + ->with($this->companyUserTransferMock, $this->restWriteCompanyUserRequestTransferMock) + ->willReturn(true); + + $this->pluginExecutor->executePreUpdateValidationPlugins( + $this->companyUserTransferMock, + $this->restWriteCompanyUserRequestTransferMock, + ); + } + + /** + * @return void + */ + public function testExecutePreDeletePlugins(): void + { + $this->companyUserPreDeleteValidationPluginMock->expects(static::atLeastOnce()) + ->method('validate') + ->with($this->companyUserTransferMock, $this->restDeleteCompanyUserRequestTransfer) + ->willReturn(true); + + $this->pluginExecutor->executePreDeleteValidationPlugins( + $this->companyUserTransferMock, + $this->restDeleteCompanyUserRequestTransfer, + ); + } } diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdaterTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdaterTest.php index 740163d..ad3aa8d 100644 --- a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdaterTest.php +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Updater/CompanyUserUpdaterTest.php @@ -3,6 +3,7 @@ namespace FondOfImpala\Zed\CompanyUsersRestApi\Business\Updater; use Codeception\Test\Unit; +use FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyRoleCollectionReaderInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Business\Reader\CompanyUserReaderInterface; use FondOfImpala\Zed\CompanyUsersRestApi\Communication\Plugin\PermissionExtension\UpdateCompanyUserPermissionPlugin; @@ -12,6 +13,7 @@ use Generated\Shared\Transfer\CompanyUserResponseTransfer; use Generated\Shared\Transfer\CompanyUserTransfer; use Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer; +use PHPUnit\Framework\MockObject\MockObject; class CompanyUserUpdaterTest extends Unit { @@ -35,6 +37,11 @@ class CompanyUserUpdaterTest extends Unit */ protected $permissionFacadeMock; + /** + * @var \FondOfImpala\Zed\CompanyUsersRestApi\Business\PluginExecutor\CompanyUserPluginExecutorInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected CompanyUserPluginExecutorInterface|MockObject $pluginExecutorMock; + /** * @var \Generated\Shared\Transfer\RestWriteCompanyUserRequestTransfer&\PHPUnit\Framework\MockObject\MockObject|\PHPUnit\Framework\MockObject\MockObject */ @@ -88,6 +95,10 @@ protected function _before(): void ->disableOriginalConstructor() ->getMock(); + $this->pluginExecutorMock = $this->getMockBuilder(CompanyUserPluginExecutorInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->restWriteCompanyUserRequestTransferMock = $this->getMockBuilder(RestWriteCompanyUserRequestTransfer::class) ->disableOriginalConstructor() ->getMock(); @@ -113,6 +124,7 @@ protected function _before(): void $this->companyRoleCollectionReaderMock, $this->companyUserFacadeMock, $this->permissionFacadeMock, + $this->pluginExecutorMock, ); } @@ -160,6 +172,10 @@ public function testUpdateByRestWriteCompanyUserRequest(): void ->method('setCustomer') ->willReturnSelf(); + $this->pluginExecutorMock->expects(static::atLeastOnce()) + ->method('executePreUpdateValidationPlugins') + ->willReturn(true); + $this->companyUserFacadeMock->expects(static::atLeastOnce()) ->method('update') ->with($this->updatableCompanyUserTransferMock) @@ -319,6 +335,10 @@ public function testUpdateByRestWriteCompanyUserRequestWithError(): void ->method('setCustomer') ->willReturnSelf(); + $this->pluginExecutorMock->expects(static::atLeastOnce()) + ->method('executePreUpdateValidationPlugins') + ->willReturn(true); + $this->companyUserFacadeMock->expects(static::atLeastOnce()) ->method('update') ->with($this->updatableCompanyUserTransferMock) diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationTest.php new file mode 100644 index 0000000..39c4af1 --- /dev/null +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserDeleteValidationTest.php @@ -0,0 +1,243 @@ +repositoryMock = $this->getMockBuilder(CompanyUsersRestApiRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->configMock = $this->getMockBuilder(CompanyUsersRestApiConfig::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserTransferMock = $this->getMockBuilder(CompanyUserTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserTransferMock2 = $this->getMockBuilder(CompanyUserTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->restDeleteCompanyUserRequestTransferMock = $this->getMockBuilder(RestDeleteCompanyUserRequestTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserCollectionTransferMock = $this->getMockBuilder(CompanyUserCollectionTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->validation = new CompanyUserDeleteValidation( + $this->repositoryMock, + $this->configMock, + ); + } + + /** + * @return void + */ + public function testValidateWithOnlyOneCompanyUserFound(): void + { + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserByFkCompany') + ->willReturn($this->companyUserCollectionTransferMock); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCompany') + ->willReturn(99); + + $this->companyUserCollectionTransferMock + ->expects(static::atLeastOnce()) + ->method('getCompanyUsers') + ->willReturn(new ArrayObject([$this->companyUserTransferMock])); + + static::assertFalse($this->validation->validate($this->companyUserTransferMock, $this->restDeleteCompanyUserRequestTransferMock)); + } + + /** + * @return void + */ + public function testValidateWithRoleIsProtected(): void + { + $protectedRole = 'admin'; + $unProtectedRole = 'distributor'; + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserByFkCompany') + ->willReturn($this->companyUserCollectionTransferMock); + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserRolesByCompanyUser') + ->willReturn([$unProtectedRole, $protectedRole]); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCompany') + ->willReturn(99); + + $this->configMock + ->expects(static::atLeastOnce()) + ->method('getProtectedRoles') + ->willReturn([$protectedRole]); + + $this->companyUserCollectionTransferMock + ->expects(static::atLeastOnce()) + ->method('getCompanyUsers') + ->willReturn(new ArrayObject([$this->companyUserTransferMock, $this->companyUserTransferMock])); + + static::assertFalse($this->validation->validate($this->companyUserTransferMock, $this->restDeleteCompanyUserRequestTransferMock)); + } + + /** + * @return void + */ + public function testValidatePreventDeletingOwnCompanyUser(): void + { + $protectedRole = 'admin'; + $unProtectedRole = 'distributor'; + $idCustomer = 44; + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserByFkCompany') + ->willReturn($this->companyUserCollectionTransferMock); + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserRolesByCompanyUser') + ->willReturn([$unProtectedRole]); + + $this->restDeleteCompanyUserRequestTransferMock + ->expects(static::atLeastOnce()) + ->method('getIdCustomer') + ->willReturn($idCustomer); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCompany') + ->willReturn(99); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCustomer') + ->willReturn($idCustomer); + + $this->configMock + ->expects(static::atLeastOnce()) + ->method('getProtectedRoles') + ->willReturn([$protectedRole]); + + $this->companyUserCollectionTransferMock + ->expects(static::atLeastOnce()) + ->method('getCompanyUsers') + ->willReturn(new ArrayObject([$this->companyUserTransferMock, $this->companyUserTransferMock])); + + static::assertFalse($this->validation->validate($this->companyUserTransferMock, $this->restDeleteCompanyUserRequestTransferMock)); + } + + /** + * @return void + */ + public function testValidateCanDelete(): void + { + $protectedRole = 'admin'; + $unProtectedRole = 'distributor'; + $idCustomer = 44; + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserByFkCompany') + ->willReturn($this->companyUserCollectionTransferMock); + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserRolesByCompanyUser') + ->willReturn([$unProtectedRole]); + + $this->restDeleteCompanyUserRequestTransferMock + ->expects(static::atLeastOnce()) + ->method('getIdCustomer') + ->willReturn($idCustomer); + + $this->companyUserTransferMock2 + ->expects(static::atLeastOnce()) + ->method('getFkCompany') + ->willReturn(99); + + $this->companyUserTransferMock2 + ->expects(static::atLeastOnce()) + ->method('getFkCustomer') + ->willReturn(99); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCustomer') + ->willReturn($idCustomer); + + $this->configMock + ->expects(static::atLeastOnce()) + ->method('getProtectedRoles') + ->willReturn([$protectedRole]); + + $this->companyUserCollectionTransferMock + ->expects(static::atLeastOnce()) + ->method('getCompanyUsers') + ->willReturn(new ArrayObject([$this->companyUserTransferMock2, $this->companyUserTransferMock])); + + static::assertTrue($this->validation->validate($this->companyUserTransferMock2, $this->restDeleteCompanyUserRequestTransferMock)); + } +} diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationTest.php new file mode 100644 index 0000000..37f093c --- /dev/null +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Business/Validation/CompanyUserUpdateValidationTest.php @@ -0,0 +1,212 @@ +repositoryMock = $this->getMockBuilder(CompanyUsersRestApiRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->configMock = $this->getMockBuilder(CompanyUsersRestApiConfig::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserTransferMock = $this->getMockBuilder(CompanyUserTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserTransferMock2 = $this->getMockBuilder(CompanyUserTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->restWriteCompanyUserRequestTransferMock = $this->getMockBuilder(RestWriteCompanyUserRequestTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserCollectionTransferMock = $this->getMockBuilder(CompanyUserCollectionTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->validation = new CompanyUserUpdateValidation( + $this->repositoryMock, + $this->configMock, + ); + } + + /** + * @return void + */ + public function testValidateWithOnlyOneCompanyUserFound(): void + { + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserByFkCompany') + ->willReturn($this->companyUserCollectionTransferMock); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCompany') + ->willReturn(99); + + $this->companyUserCollectionTransferMock + ->expects(static::atLeastOnce()) + ->method('getCompanyUsers') + ->willReturn(new ArrayObject([$this->companyUserTransferMock])); + + static::assertFalse($this->validation->validate($this->companyUserTransferMock, $this->restWriteCompanyUserRequestTransferMock)); + } + + /** + * @return void + */ + public function testValidateWithRoleIsProtected(): void + { + $protectedRoleName = 'admin'; + $unProtectedRoleName = 'distributor'; + $protectedRole = [ + SpyCompanyRoleTableMap::COL_NAME => $protectedRoleName, + SpyCompanyRoleTableMap::COL_UUID => 'asdasdas', + SpyCompanyRoleToCompanyUserTableMap::COL_FK_COMPANY_USER => 99, + ]; + $unProtectedRole = [ + SpyCompanyRoleTableMap::COL_NAME => $unProtectedRoleName, + SpyCompanyRoleTableMap::COL_UUID => 'asdasasdasdadas', + SpyCompanyRoleToCompanyUserTableMap::COL_FK_COMPANY_USER => 2, + ]; + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserByFkCompany') + ->willReturn($this->companyUserCollectionTransferMock); + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserRolesByFkCompany') + ->willReturn([$unProtectedRole, $protectedRole]); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCompany') + ->willReturn(99); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getIdCompanyUser') + ->willReturn(99); + + $this->configMock + ->expects(static::atLeastOnce()) + ->method('getProtectedRoles') + ->willReturn([$protectedRoleName]); + + $this->companyUserCollectionTransferMock + ->expects(static::atLeastOnce()) + ->method('getCompanyUsers') + ->willReturn(new ArrayObject([$this->companyUserTransferMock, $this->companyUserTransferMock])); + + static::assertFalse($this->validation->validate($this->companyUserTransferMock, $this->restWriteCompanyUserRequestTransferMock)); + } + + /** + * @return void + */ + public function testValidateCanUpdate(): void + { + $protectedRoleName = 'admin'; + $unProtectedRoleName = 'distributor'; + $protectedRole = [ + SpyCompanyRoleTableMap::COL_NAME => $protectedRoleName, + SpyCompanyRoleTableMap::COL_UUID => 'asdasdas', + SpyCompanyRoleToCompanyUserTableMap::COL_FK_COMPANY_USER => 1, + ]; + $unProtectedRole = [ + SpyCompanyRoleTableMap::COL_NAME => $unProtectedRoleName, + SpyCompanyRoleTableMap::COL_UUID => 'asdasasdasdadas', + SpyCompanyRoleToCompanyUserTableMap::COL_FK_COMPANY_USER => 99, + ]; + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserByFkCompany') + ->willReturn($this->companyUserCollectionTransferMock); + + $this->repositoryMock + ->expects(static::atLeastOnce()) + ->method('findCompanyUserRolesByFkCompany') + ->willReturn([$unProtectedRole, $protectedRole]); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getFkCompany') + ->willReturn(99); + + $this->companyUserTransferMock + ->expects(static::atLeastOnce()) + ->method('getIdCompanyUser') + ->willReturn(99); + + $this->configMock + ->expects(static::atLeastOnce()) + ->method('getProtectedRoles') + ->willReturn([$protectedRoleName]); + + $this->companyUserCollectionTransferMock + ->expects(static::atLeastOnce()) + ->method('getCompanyUsers') + ->willReturn(new ArrayObject([$this->companyUserTransferMock, $this->companyUserTransferMock])); + + static::assertTrue($this->validation->validate($this->companyUserTransferMock, $this->restWriteCompanyUserRequestTransferMock)); + } +} diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/DisallowSelfDeletionValidationPluginTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/DisallowSelfDeletionValidationPluginTest.php new file mode 100644 index 0000000..511f1e6 --- /dev/null +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/DisallowSelfDeletionValidationPluginTest.php @@ -0,0 +1,68 @@ +facadeMock = $this->getMockBuilder(CompanyUsersRestApiFacade::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserTransferMock = $this->getMockBuilder(CompanyUserTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->restDeleteCompanyUserRequestTransferMock = $this->getMockBuilder(RestDeleteCompanyUserRequestTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->plugin = new DisallowSelfDeletionValidationPlugin(); + $this->plugin->setFacade($this->facadeMock); + } + + /** + * @return void + */ + public function testValidate(): void + { + $this->facadeMock->expects(static::atLeastOnce()) + ->method('canDeleteCompanyUser') + ->willReturn(true); + + $this->plugin->validate($this->companyUserTransferMock, $this->restDeleteCompanyUserRequestTransferMock); + } +} diff --git a/tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPluginTest.php b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPluginTest.php new file mode 100644 index 0000000..8c3b3bf --- /dev/null +++ b/tests/FondOfImpala/Zed/CompanyUsersRestApi/Communication/Plugin/LastAvailableRoleProtectionOnUpdateValidationPluginTest.php @@ -0,0 +1,68 @@ +facadeMock = $this->getMockBuilder(CompanyUsersRestApiFacade::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->companyUserTransferMock = $this->getMockBuilder(CompanyUserTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->restWriteCompanyUserRequestTransferMock = $this->getMockBuilder(RestWriteCompanyUserRequestTransfer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->plugin = new LastAvailableRoleProtectionOnUpdateValidationPlugin(); + $this->plugin->setFacade($this->facadeMock); + } + + /** + * @return void + */ + public function testValidate(): void + { + $this->facadeMock->expects(static::atLeastOnce()) + ->method('canUpdateCompanyUser') + ->willReturn(true); + + $this->plugin->validate($this->companyUserTransferMock, $this->restWriteCompanyUserRequestTransferMock); + } +}