From d6154a93f08e7906dca1474706161a8462356a8c Mon Sep 17 00:00:00 2001 From: AntonKhabiuk Date: Mon, 5 Aug 2024 18:18:54 +0300 Subject: [PATCH] CC-34136 Quicksight user registration and persistence --- composer.json | 4 +- .../Transfer/amazon_quicksight.transfer.xml | 26 +++ .../AmazonQuicksightConfig.php | 6 +- .../AmazonQuicksightBusinessFactory.php | 57 +++++ .../Business/AmazonQuicksightFacade.php | 17 ++ .../AmazonQuicksightFacadeInterface.php | 19 ++ .../ApiClient/AmazonQuicksightApiClient.php | 124 +++++++++++ .../AmazonQuicksightApiClientInterface.php | 21 ++ .../Creator/QuicksightUserCreator.php | 135 ++++++++++++ .../QuicksightUserCreatorInterface.php | 22 ++ .../AmazonQuicksightRequestDataFormatter.php | 30 +++ ...uicksightRequestDataFormatterInterface.php | 18 ++ .../Mapper/AmazonQuicksightMapper.php | 44 ++++ .../AmazonQuicksightMapperInterface.php | 37 ++++ .../User/QuicksightUserPostCreatePlugin.php | 39 ++++ .../AmazonQuicksightEntityManager.php | 19 ++ ...AmazonQuicksightEntityManagerInterface.php | 8 + .../AmazonQuicksightPersistenceFactory.php | 8 + .../Propel/Mapper/QuicksightUserMapper.php | 40 ++++ ...ateQuicksightUsersForUserTransfersTest.php | 199 ++++++++++++++++++ .../AmazonQuicksightBusinessTester.php | 49 +++++ .../Zed/AmazonQuicksight/codeception.yml | 22 ++ 22 files changed, 940 insertions(+), 4 deletions(-) create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClient.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClientInterface.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/Creator/QuicksightUserCreator.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/Creator/QuicksightUserCreatorInterface.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/Formatter/AmazonQuicksightRequestDataFormatter.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/Formatter/AmazonQuicksightRequestDataFormatterInterface.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapper.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapperInterface.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Communication/Plugin/User/QuicksightUserPostCreatePlugin.php create mode 100644 src/SprykerEco/Zed/AmazonQuicksight/Persistence/Propel/Mapper/QuicksightUserMapper.php create mode 100644 tests/SprykerEcoTest/Zed/AmazonQuicksight/Business/Facade/CreateQuicksightUsersForUserTransfersTest.php create mode 100644 tests/SprykerEcoTest/Zed/AmazonQuicksight/_support/AmazonQuicksightBusinessTester.php diff --git a/composer.json b/composer.json index 33090a1..25e934b 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,9 @@ }, "require-dev": { "phpstan/phpstan": "*", - "spryker/code-sniffer": "*" + "spryker/code-sniffer": "*", + "spryker/propel": "*", + "spryker/testify": "*" }, "autoload": { "psr-4": { diff --git a/src/SprykerEco/Shared/AmazonQuicksight/Transfer/amazon_quicksight.transfer.xml b/src/SprykerEco/Shared/AmazonQuicksight/Transfer/amazon_quicksight.transfer.xml index dc33cc7..e722cee 100644 --- a/src/SprykerEco/Shared/AmazonQuicksight/Transfer/amazon_quicksight.transfer.xml +++ b/src/SprykerEco/Shared/AmazonQuicksight/Transfer/amazon_quicksight.transfer.xml @@ -12,8 +12,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/SprykerEco/Zed/AmazonQuicksight/AmazonQuicksightConfig.php b/src/SprykerEco/Zed/AmazonQuicksight/AmazonQuicksightConfig.php index bbf82d3..7260db8 100644 --- a/src/SprykerEco/Zed/AmazonQuicksight/AmazonQuicksightConfig.php +++ b/src/SprykerEco/Zed/AmazonQuicksight/AmazonQuicksightConfig.php @@ -16,7 +16,7 @@ class AmazonQuicksightConfig extends AbstractBundleConfig /** * @var string */ - protected const QUICKSIGHT_USER_REGISTER_NAMESPACE = 'default'; + protected const QUICKSIGHT_REGISTER_USER_NAMESPACE = 'default'; /** * @var string @@ -66,9 +66,9 @@ public function getAwsAccountId(): string * * @return string */ - public function getQuicksightUserRegisterNamespace(): string + public function getQuicksightRegisterUserNamespace(): string { - return static::QUICKSIGHT_USER_REGISTER_NAMESPACE; + return static::QUICKSIGHT_REGISTER_USER_NAMESPACE; } /** diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightBusinessFactory.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightBusinessFactory.php index 07adc4a..af1dc79 100644 --- a/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightBusinessFactory.php +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightBusinessFactory.php @@ -8,6 +8,16 @@ namespace SprykerEco\Zed\AmazonQuicksight\Business; use Spryker\Zed\Kernel\Business\AbstractBusinessFactory; +use SprykerEco\Zed\AmazonQuicksight\AmazonQuicksightDependencyProvider; +use SprykerEco\Zed\AmazonQuicksight\Business\ApiClient\AmazonQuicksightApiClient; +use SprykerEco\Zed\AmazonQuicksight\Business\ApiClient\AmazonQuicksightApiClientInterface; +use SprykerEco\Zed\AmazonQuicksight\Business\Creator\QuicksightUserCreator; +use SprykerEco\Zed\AmazonQuicksight\Business\Creator\QuicksightUserCreatorInterface; +use SprykerEco\Zed\AmazonQuicksight\Business\Formatter\AmazonQuicksightRequestDataFormatter; +use SprykerEco\Zed\AmazonQuicksight\Business\Formatter\AmazonQuicksightRequestDataFormatterInterface; +use SprykerEco\Zed\AmazonQuicksight\Business\Mapper\AmazonQuicksightMapper; +use SprykerEco\Zed\AmazonQuicksight\Business\Mapper\AmazonQuicksightMapperInterface; +use SprykerEco\Zed\AmazonQuicksight\Dependency\External\AmazonQuicksightToAwsQuicksightClientInterface; /** * @method \SprykerEco\Zed\AmazonQuicksight\AmazonQuicksightConfig getConfig() @@ -16,4 +26,51 @@ */ class AmazonQuicksightBusinessFactory extends AbstractBusinessFactory { + /** + * @return \SprykerEco\Zed\AmazonQuicksight\Business\Creator\QuicksightUserCreatorInterface + */ + public function createQuicksightUserCreator(): QuicksightUserCreatorInterface + { + return new QuicksightUserCreator( + $this->createAmazonQuicksightApiClient(), + $this->getEntityManager(), + ); + } + + /** + * @return \SprykerEco\Zed\AmazonQuicksight\Business\ApiClient\AmazonQuicksightApiClientInterface + */ + public function createAmazonQuicksightApiClient(): AmazonQuicksightApiClientInterface + { + return new AmazonQuicksightApiClient( + $this->getConfig(), + $this->createAmazonQuicksightMapper(), + $this->createAmazonQuicksightRequestDataFormatter(), + $this->getAwsQuicksightClient(), + ); + } + + /** + * @return \SprykerEco\Zed\AmazonQuicksight\Business\Mapper\AmazonQuicksightMapperInterface + */ + public function createAmazonQuicksightMapper(): AmazonQuicksightMapperInterface + { + return new AmazonQuicksightMapper(); + } + + /** + * @return \SprykerEco\Zed\AmazonQuicksight\Business\Formatter\AmazonQuicksightRequestDataFormatterInterface + */ + public function createAmazonQuicksightRequestDataFormatter(): AmazonQuicksightRequestDataFormatterInterface + { + return new AmazonQuicksightRequestDataFormatter(); + } + + /** + * @return \SprykerEco\Zed\AmazonQuicksight\Dependency\External\AmazonQuicksightToAwsQuicksightClientInterface + */ + public function getAwsQuicksightClient(): AmazonQuicksightToAwsQuicksightClientInterface + { + return $this->getProvidedDependency(AmazonQuicksightDependencyProvider::AWS_QUICKSIGHT_CLIENT); + } } diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacade.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacade.php index c8b7f3a..f186151 100644 --- a/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacade.php +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacade.php @@ -7,6 +7,7 @@ namespace SprykerEco\Zed\AmazonQuicksight\Business; +use Generated\Shared\Transfer\UserCollectionResponseTransfer; use Spryker\Zed\Kernel\Business\AbstractFacade; /** @@ -16,4 +17,20 @@ */ class AmazonQuicksightFacade extends AbstractFacade implements AmazonQuicksightFacadeInterface { + /** + * {@inheritDoc} + * + * @api + * + * @param \Generated\Shared\Transfer\UserCollectionResponseTransfer $userCollectionResponseTransfer + * + * @return \Generated\Shared\Transfer\UserCollectionResponseTransfer + */ + public function createQuicksightUsersForUserTransfers( + UserCollectionResponseTransfer $userCollectionResponseTransfer + ): UserCollectionResponseTransfer { + return $this->getFactory() + ->createQuicksightUserCreator() + ->createQuicksightUsersForUserTransfers($userCollectionResponseTransfer); + } } diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacadeInterface.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacadeInterface.php index 30abb24..6e50659 100644 --- a/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacadeInterface.php +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/AmazonQuicksightFacadeInterface.php @@ -7,6 +7,25 @@ namespace SprykerEco\Zed\AmazonQuicksight\Business; +use Generated\Shared\Transfer\UserCollectionResponseTransfer; + interface AmazonQuicksightFacadeInterface { + /** + * Specification: + * - Expects `UserCollectionResponseTransfer.users.quicksightUser.role` to be set. + * - Sends request to AWS API to register Quicksight users. For more information see {@link https://docs.aws.amazon.com/quicksight/latest/APIReference/API_RegisterUser.html}. + * - Adds errors to `UserCollectionResponseTransfer.errors` if Quicksight user registration failed. + * - Persists successfully registered Quicksight users in the database. + * - Returns `UserCollectionResponseTransfer` with updated `UserTransfers`. + * + * @api + * + * @param \Generated\Shared\Transfer\UserCollectionResponseTransfer $userCollectionResponseTransfer + * + * @return \Generated\Shared\Transfer\UserCollectionResponseTransfer + */ + public function createQuicksightUsersForUserTransfers( + UserCollectionResponseTransfer $userCollectionResponseTransfer + ): UserCollectionResponseTransfer; } diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClient.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClient.php new file mode 100644 index 0000000..8786cb1 --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClient.php @@ -0,0 +1,124 @@ +amazonQuicksightConfig = $amazonQuicksightConfig; + $this->amazonQuicksightMapper = $amazonQuicksightMapper; + $this->amazonQuicksightRequestDataFormatter = $amazonQuicksightRequestDataFormatter; + $this->amazonQuicksightToAwsQuicksightClient = $amazonQuicksightToAwsQuicksightClient; + } + + /** + * @param \Generated\Shared\Transfer\UserTransfer $userTransfer + * + * @return \Generated\Shared\Transfer\QuicksightUserRegisterResponseTransfer + */ + public function registerUser(UserTransfer $userTransfer): QuicksightUserRegisterResponseTransfer + { + $quicksightUserRegisterRequestTransfer = $this->createQuicksightUserRegisterRequestTransfer(); + $quicksightUserRegisterRequestTransfer = $this->amazonQuicksightMapper->mapUserTransferToQuicksightUserRegisterRequestTransfer( + $userTransfer, + $quicksightUserRegisterRequestTransfer, + ); + + $requestData = $this->amazonQuicksightRequestDataFormatter->formatRequestData( + $quicksightUserRegisterRequestTransfer->toArray(true, true), + ); + + $quicksightUserRegisterResponseTransfer = new QuicksightUserRegisterResponseTransfer(); + try { + $response = $this->amazonQuicksightToAwsQuicksightClient->registerUser($requestData); + } catch (QuickSightException $quickSightException) { + return $quicksightUserRegisterResponseTransfer->addError( + (new ErrorTransfer())->setMessage($quickSightException->getAwsErrorMessage()), + ); + } + + if (!$response->hasKey(static::RESPONSE_KEY_USER)) { + return $quicksightUserRegisterResponseTransfer->addError( + (new ErrorTransfer())->setMessage(static::ERROR_MESSAGE_USER_REGISTRATION_FAILED), + ); + } + + $quicksightUserTransfer = $this->amazonQuicksightMapper->mapQuicksightUserDataToQuicksightUserTransfer( + $response->get(static::RESPONSE_KEY_USER), + $userTransfer->getQuicksightUserOrFail(), + ); + + return $quicksightUserRegisterResponseTransfer->setQuicksightUser($quicksightUserTransfer); + } + + /** + * @return \Generated\Shared\Transfer\QuicksightUserRegisterRequestTransfer + */ + protected function createQuicksightUserRegisterRequestTransfer(): QuicksightUserRegisterRequestTransfer + { + return (new QuicksightUserRegisterRequestTransfer()) + ->setIdentityType(static::QUICKSIGHT_USER_IDENTITY_TYPE) + ->setAwsAccountId($this->amazonQuicksightConfig->getAwsAccountId()) + ->setNamespace($this->amazonQuicksightConfig->getQuicksightRegisterUserNamespace()); + } +} diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClientInterface.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClientInterface.php new file mode 100644 index 0000000..d7ebad4 --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/ApiClient/AmazonQuicksightApiClientInterface.php @@ -0,0 +1,21 @@ +amazonQuicksightApiClient = $amazonQuicksightApiClient; + $this->amazonQuicksightEntityManager = $amazonQuicksightEntityManager; + } + + /** + * @param \Generated\Shared\Transfer\UserCollectionResponseTransfer $userCollectionResponseTransfer + * + * @return \Generated\Shared\Transfer\UserCollectionResponseTransfer + */ + public function createQuicksightUsersForUserTransfers( + UserCollectionResponseTransfer $userCollectionResponseTransfer + ): UserCollectionResponseTransfer { + $userTransfersWithQuicksightUserRole = $this->extractUserTransfersWithQuicksightUserRole( + $userCollectionResponseTransfer->getUsers(), + ); + + if ($userTransfersWithQuicksightUserRole === []) { + return $userCollectionResponseTransfer; + } + + return $this->getTransactionHandler()->handleTransaction(function () use ($userCollectionResponseTransfer, $userTransfersWithQuicksightUserRole) { + return $this->executeCreateQuicksightUsersForUsersTransaction( + $userCollectionResponseTransfer, + $userTransfersWithQuicksightUserRole, + ); + }); + } + + /** + * @param \Generated\Shared\Transfer\UserCollectionResponseTransfer $userCollectionResponseTransfer + * @param array $userTransfers + * + * @return \Generated\Shared\Transfer\UserCollectionResponseTransfer + */ + protected function executeCreateQuicksightUsersForUsersTransaction( + UserCollectionResponseTransfer $userCollectionResponseTransfer, + array $userTransfers + ): UserCollectionResponseTransfer { + foreach ($userTransfers as $entityIdentifier => $userTransfer) { + $quicksightUserRegisterResponseTransfer = $this->amazonQuicksightApiClient->registerUser($userTransfer); + if ($quicksightUserRegisterResponseTransfer->getErrors()->count() !== 0) { + $userCollectionResponseTransfer = $this->addErrorsToUserCollectionResponse( + $userCollectionResponseTransfer, + $quicksightUserRegisterResponseTransfer->getErrors(), + $entityIdentifier, + ); + + continue; + } + + $quicksightUserTransfer = $quicksightUserRegisterResponseTransfer->getQuicksightUserOrFail(); + $quicksightUserTransfer->setFkUser($userTransfer->getIdUserOrFail()); + + $quicksightUserTransfer = $this->amazonQuicksightEntityManager->createQuicksightUser($quicksightUserTransfer); + $userTransfer->setQuicksightUser($quicksightUserTransfer); + } + + return $userCollectionResponseTransfer; + } + + /** + * @param \ArrayObject $userTransfers + * + * @return array + */ + protected function extractUserTransfersWithQuicksightUserRole(ArrayObject $userTransfers): array + { + $extractedUserTransfers = []; + foreach ($userTransfers as $entityIdentifier => $userTransfer) { + if ($userTransfer->getQuicksightUser() && $userTransfer->getQuicksightUserOrFail()->getRole()) { + $extractedUserTransfers[$entityIdentifier] = $userTransfer; + } + } + + return $extractedUserTransfers; + } + + /** + * @param \Generated\Shared\Transfer\UserCollectionResponseTransfer $userCollectionResponseTransfer + * @param \ArrayObject $errorTransfers + * @param string $entityIdentifier + * + * @return \Generated\Shared\Transfer\UserCollectionResponseTransfer + */ + protected function addErrorsToUserCollectionResponse( + UserCollectionResponseTransfer $userCollectionResponseTransfer, + ArrayObject $errorTransfers, + string $entityIdentifier + ): UserCollectionResponseTransfer { + foreach ($errorTransfers as $errorTransfer) { + $errorTransfer->setEntityIdentifier($entityIdentifier); + + $userCollectionResponseTransfer->addError($errorTransfer); + } + + return $userCollectionResponseTransfer; + } +} diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/Creator/QuicksightUserCreatorInterface.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/Creator/QuicksightUserCreatorInterface.php new file mode 100644 index 0000000..d476f92 --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/Creator/QuicksightUserCreatorInterface.php @@ -0,0 +1,22 @@ + $requestData + * + * @return array + */ + public function formatRequestData(array $requestData): array + { + $formattedData = []; + foreach ($requestData as $key => $value) { + if (is_array($value)) { + $value = $this->formatRequestData($value); + } + + $formattedData[ucfirst($key)] = $value; + } + + return $formattedData; + } +} diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/Formatter/AmazonQuicksightRequestDataFormatterInterface.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/Formatter/AmazonQuicksightRequestDataFormatterInterface.php new file mode 100644 index 0000000..c5ed2f8 --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/Formatter/AmazonQuicksightRequestDataFormatterInterface.php @@ -0,0 +1,18 @@ + $requestData + * + * @return array + */ + public function formatRequestData(array $requestData): array; +} diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapper.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapper.php new file mode 100644 index 0000000..06b22c2 --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapper.php @@ -0,0 +1,44 @@ +setEmail($userTransfer->getUsernameOrFail()) + ->setUserName($userTransfer->getUsernameOrFail()) + ->setUserRole(strtoupper($userTransfer->getQuicksightUserOrFail()->getRoleOrFail())); + } + + /** + * @param array $quicksightUserData + * @param \Generated\Shared\Transfer\QuicksightUserTransfer $quicksightUserTransfer + * + * @return \Generated\Shared\Transfer\QuicksightUserTransfer + */ + public function mapQuicksightUserDataToQuicksightUserTransfer( + array $quicksightUserData, + QuicksightUserTransfer $quicksightUserTransfer + ): QuicksightUserTransfer { + return $quicksightUserTransfer->fromArray($quicksightUserData, true); + } +} diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapperInterface.php b/src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapperInterface.php new file mode 100644 index 0000000..8bcb1b8 --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Business/Mapper/AmazonQuicksightMapperInterface.php @@ -0,0 +1,37 @@ + $quicksightUserData + * @param \Generated\Shared\Transfer\QuicksightUserTransfer $quicksightUserTransfer + * + * @return \Generated\Shared\Transfer\QuicksightUserTransfer + */ + public function mapQuicksightUserDataToQuicksightUserTransfer( + array $quicksightUserData, + QuicksightUserTransfer $quicksightUserTransfer + ): QuicksightUserTransfer; +} diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Communication/Plugin/User/QuicksightUserPostCreatePlugin.php b/src/SprykerEco/Zed/AmazonQuicksight/Communication/Plugin/User/QuicksightUserPostCreatePlugin.php new file mode 100644 index 0000000..0cf4fba --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Communication/Plugin/User/QuicksightUserPostCreatePlugin.php @@ -0,0 +1,39 @@ +getFacade()->createQuicksightUsersForUserTransfers($userCollectionResponseTransfer); + } +} diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManager.php b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManager.php index 1676134..9d8132a 100644 --- a/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManager.php +++ b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManager.php @@ -7,6 +7,8 @@ namespace SprykerEco\Zed\AmazonQuicksight\Persistence; +use Generated\Shared\Transfer\QuicksightUserTransfer; +use Orm\Zed\AmazonQuicksight\Persistence\SpyQuicksightUser; use Spryker\Zed\Kernel\Persistence\AbstractEntityManager; /** @@ -14,4 +16,21 @@ */ class AmazonQuicksightEntityManager extends AbstractEntityManager implements AmazonQuicksightEntityManagerInterface { + /** + * @param \Generated\Shared\Transfer\QuicksightUserTransfer $quicksightUserTransfer + * + * @return \Generated\Shared\Transfer\QuicksightUserTransfer + */ + public function createQuicksightUser(QuicksightUserTransfer $quicksightUserTransfer): QuicksightUserTransfer + { + $quicksightUserEntity = $this->getFactory() + ->createQuicksightUserMapper() + ->mapQuicksightUserTransferToQuicksightUserEntity($quicksightUserTransfer, new SpyQuicksightUser()); + + $quicksightUserEntity->save(); + + return $this->getFactory() + ->createQuicksightUserMapper() + ->mapQuicksightUserEntityToQuicksightUserTransfer($quicksightUserEntity, $quicksightUserTransfer); + } } diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManagerInterface.php b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManagerInterface.php index 067d7d0..00e280f 100644 --- a/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManagerInterface.php +++ b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightEntityManagerInterface.php @@ -7,6 +7,14 @@ namespace SprykerEco\Zed\AmazonQuicksight\Persistence; +use Generated\Shared\Transfer\QuicksightUserTransfer; + interface AmazonQuicksightEntityManagerInterface { + /** + * @param \Generated\Shared\Transfer\QuicksightUserTransfer $quicksightUserTransfer + * + * @return \Generated\Shared\Transfer\QuicksightUserTransfer + */ + public function createQuicksightUser(QuicksightUserTransfer $quicksightUserTransfer): QuicksightUserTransfer; } diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightPersistenceFactory.php b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightPersistenceFactory.php index 2c52f7c..d2a4da7 100644 --- a/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightPersistenceFactory.php +++ b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/AmazonQuicksightPersistenceFactory.php @@ -8,6 +8,7 @@ namespace SprykerEco\Zed\AmazonQuicksight\Persistence; use Spryker\Zed\Kernel\Persistence\AbstractPersistenceFactory; +use SprykerEco\Zed\AmazonQuicksight\Persistence\Propel\Mapper\QuicksightUserMapper; /** * @method \SprykerEco\Zed\AmazonQuicksight\AmazonQuicksightConfig getConfig() @@ -16,4 +17,11 @@ */ class AmazonQuicksightPersistenceFactory extends AbstractPersistenceFactory { + /** + * @return \SprykerEco\Zed\AmazonQuicksight\Persistence\Propel\Mapper\QuicksightUserMapper + */ + public function createQuicksightUserMapper(): QuicksightUserMapper + { + return new QuicksightUserMapper(); + } } diff --git a/src/SprykerEco/Zed/AmazonQuicksight/Persistence/Propel/Mapper/QuicksightUserMapper.php b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/Propel/Mapper/QuicksightUserMapper.php new file mode 100644 index 0000000..b9bd299 --- /dev/null +++ b/src/SprykerEco/Zed/AmazonQuicksight/Persistence/Propel/Mapper/QuicksightUserMapper.php @@ -0,0 +1,40 @@ +fromArray($quicksightUserTransfer->modifiedToArray()); + } + + /** + * @param \Orm\Zed\AmazonQuicksight\Persistence\SpyQuicksightUser $quicksightUserEntity + * @param \Generated\Shared\Transfer\QuicksightUserTransfer $quicksightUserTransfer + * + * @return \Generated\Shared\Transfer\QuicksightUserTransfer + */ + public function mapQuicksightUserEntityToQuicksightUserTransfer( + SpyQuicksightUser $quicksightUserEntity, + QuicksightUserTransfer $quicksightUserTransfer + ): QuicksightUserTransfer { + return $quicksightUserTransfer->fromArray($quicksightUserEntity->toArray(), true); + } +} diff --git a/tests/SprykerEcoTest/Zed/AmazonQuicksight/Business/Facade/CreateQuicksightUsersForUserTransfersTest.php b/tests/SprykerEcoTest/Zed/AmazonQuicksight/Business/Facade/CreateQuicksightUsersForUserTransfersTest.php new file mode 100644 index 0000000..7e165be --- /dev/null +++ b/tests/SprykerEcoTest/Zed/AmazonQuicksight/Business/Facade/CreateQuicksightUsersForUserTransfersTest.php @@ -0,0 +1,199 @@ +tester->haveUserWithNotPersistedQuicksightUserRole(static::QUICKSIGHT_USER_ROLE_READER); + + $awsQuicksightClientMock = $this->getAwsQuicksightClientMock(); + $awsQuicksightClientMock->method('registerUser') + ->willReturn($this->createRegisterUserSuccessfulResponse($userTransfer)); + $this->tester->setDependency( + AmazonQuicksightDependencyProvider::AWS_QUICKSIGHT_CLIENT, + $awsQuicksightClientMock, + ); + + $userCollectionResponseTransfer = (new UserCollectionResponseTransfer())->addUser($userTransfer); + + // Act + $userCollectionResponseTransfer = $this->tester->getFacade() + ->createQuicksightUsersForUserTransfers($userCollectionResponseTransfer); + + // Assert + $this->assertCount(0, $userCollectionResponseTransfer->getErrors()); + $this->assertCount(1, $userCollectionResponseTransfer->getUsers()); + + /** @var \Generated\Shared\Transfer\UserTransfer $userTransfer */ + $userTransfer = $userCollectionResponseTransfer->getUsers()->getIterator()->current(); + $this->assertNotNull($userTransfer->getQuicksightUser()); + $this->assertNotNull($userTransfer->getQuicksightUserOrFail()->getIdQuicksightUser()); + $this->assertNotNull($userTransfer->getQuicksightUserOrFail()->getArn()); + $this->assertNotNull($userTransfer->getQuicksightUserOrFail()->getPrincipalId()); + } + + /** + * @return void + */ + public function testShouldReturnErrorWhenUserQuicksightClientThrowsException(): void + { + // Arrange + $userTransfer = $this->tester->haveUserWithNotPersistedQuicksightUserRole(static::QUICKSIGHT_USER_ROLE_READER); + + $awsQuicksightClientMock = $this->getAwsQuicksightClientMock(); + $awsQuicksightClientMock->method('registerUser') + ->willThrowException($this->getQuicksightExceptionMock(static::ERROR_MESSAGE_QUICKSIGHT_USER_REGISTER_FAILURE)); + $this->tester->setDependency( + AmazonQuicksightDependencyProvider::AWS_QUICKSIGHT_CLIENT, + $awsQuicksightClientMock, + ); + + $userCollectionResponseTransfer = (new UserCollectionResponseTransfer())->addUser($userTransfer); + + // Act + $userCollectionResponseTransfer = $this->tester->getFacade() + ->createQuicksightUsersForUserTransfers($userCollectionResponseTransfer); + + // Assert + $this->assertCount(1, $userCollectionResponseTransfer->getErrors()); + $this->assertCount(1, $userCollectionResponseTransfer->getUsers()); + + /** @var \Generated\Shared\Transfer\ErrorTransfer $errorTransfer */ + $errorTransfer = $userCollectionResponseTransfer->getErrors()->getIterator()->current(); + $this->assertSame(static::ERROR_MESSAGE_QUICKSIGHT_USER_REGISTER_FAILURE, $errorTransfer->getMessage()); + $this->assertSame((string)$userCollectionResponseTransfer->getUsers()->getIterator()->key(), $errorTransfer->getEntityIdentifier()); + + /** @var \Generated\Shared\Transfer\UserTransfer $userTransfer */ + $userTransfer = $userCollectionResponseTransfer->getUsers()->getIterator()->current(); + $this->assertNotNull($userTransfer->getQuicksightUser()); + $this->assertNull($userTransfer->getQuicksightUserOrFail()->getIdQuicksightUser()); + $this->assertNull($userTransfer->getQuicksightUserOrFail()->getArn()); + $this->assertNull($userTransfer->getQuicksightUserOrFail()->getPrincipalId()); + } + + /** + * @return void + */ + public function testShouldReturnErrorWhenQuicksightUserRegisterResponseDoesNotContainUserKey(): void + { + // Arrange + $userTransfer = $this->tester->haveUserWithNotPersistedQuicksightUserRole(static::QUICKSIGHT_USER_ROLE_READER); + + $awsQuicksightClientMock = $this->getAwsQuicksightClientMock(); + $awsQuicksightClientMock->method('registerUser') + ->willReturn(new Result()); + $this->tester->setDependency( + AmazonQuicksightDependencyProvider::AWS_QUICKSIGHT_CLIENT, + $awsQuicksightClientMock, + ); + + $userCollectionResponseTransfer = (new UserCollectionResponseTransfer())->addUser($userTransfer); + + // Act + $userCollectionResponseTransfer = $this->tester->getFacade() + ->createQuicksightUsersForUserTransfers($userCollectionResponseTransfer); + + // Assert + $this->assertCount(1, $userCollectionResponseTransfer->getErrors()); + $this->assertCount(1, $userCollectionResponseTransfer->getUsers()); + + /** @var \Generated\Shared\Transfer\ErrorTransfer $errorTransfer */ + $errorTransfer = $userCollectionResponseTransfer->getErrors()->getIterator()->current(); + $this->assertSame(static::ERROR_MESSAGE_USER_REGISTRATION_FAILED, $errorTransfer->getMessage()); + $this->assertSame((string)$userCollectionResponseTransfer->getUsers()->getIterator()->key(), $errorTransfer->getEntityIdentifier()); + + /** @var \Generated\Shared\Transfer\UserTransfer $userTransfer */ + $userTransfer = $userCollectionResponseTransfer->getUsers()->getIterator()->current(); + $this->assertNotNull($userTransfer->getQuicksightUser()); + $this->assertNull($userTransfer->getQuicksightUserOrFail()->getIdQuicksightUser()); + $this->assertNull($userTransfer->getQuicksightUserOrFail()->getArn()); + $this->assertNull($userTransfer->getQuicksightUserOrFail()->getPrincipalId()); + } + + /** + * @return \SprykerEco\Zed\AmazonQuicksight\Dependency\External\AmazonQuicksightToAwsQuicksightClientInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected function getAwsQuicksightClientMock(): AmazonQuicksightToAwsQuicksightClientInterface + { + return $this->getMockBuilder(AmazonQuicksightToAwsQuicksightClientInterface::class)->getMock(); + } + + /** + * @param \Generated\Shared\Transfer\UserTransfer $userTransfer + * + * @return \Aws\ResultInterface + */ + protected function createRegisterUserSuccessfulResponse(UserTransfer $userTransfer): ResultInterface + { + $responseData = [ + 'RequestId' => time(), + 'User' => [ + 'Arn' => 'arn:aws:quicksight:eu-central-1:123456789012:user/default/' . $userTransfer->getUsername(), + 'PrincipalId' => '123456789012', + 'Role' => $userTransfer->getQuicksightUserOrFail()->getRoleOrFail(), + ], + ]; + + return new Result($responseData); + } + + /** + * @param string $message + * + * @return \Aws\QuickSight\Exception\QuickSightException|\PHPUnit\Framework\MockObject\MockObject + */ + protected function getQuicksightExceptionMock(string $message): QuickSightException + { + $quicksightExceptionMock = $this->getMockBuilder(QuickSightException::class) + ->disableOriginalConstructor() + ->getMock(); + $quicksightExceptionMock->method('getAwsErrorMessage')->willReturn($message); + + return $quicksightExceptionMock; + } +} diff --git a/tests/SprykerEcoTest/Zed/AmazonQuicksight/_support/AmazonQuicksightBusinessTester.php b/tests/SprykerEcoTest/Zed/AmazonQuicksight/_support/AmazonQuicksightBusinessTester.php new file mode 100644 index 0000000..7670e00 --- /dev/null +++ b/tests/SprykerEcoTest/Zed/AmazonQuicksight/_support/AmazonQuicksightBusinessTester.php @@ -0,0 +1,49 @@ +haveUser([ + UserTransfer::QUICKSIGHT_USER => (new QuicksightUserBuilder([ + QuicksightUserTransfer::ROLE => $quicksightUserRole, + ]))->build(), + ]); + } +} diff --git a/tests/SprykerEcoTest/Zed/AmazonQuicksight/codeception.yml b/tests/SprykerEcoTest/Zed/AmazonQuicksight/codeception.yml index e3d070b..68f8e4f 100644 --- a/tests/SprykerEcoTest/Zed/AmazonQuicksight/codeception.yml +++ b/tests/SprykerEcoTest/Zed/AmazonQuicksight/codeception.yml @@ -1,12 +1,34 @@ namespace: SprykerEcoTest\Zed\AmazonQuicksight + paths: tests: . data: ../../../_data support: _support output: ../../../_output + coverage: enabled: true remote: false whitelist: include: - '../../../../src/*' + +suites: + Business: + path: Business + actor: AmazonQuicksightBusinessTester + modules: + enabled: + - Asserts + - \SprykerTest\Shared\Testify\Helper\Environment + - \SprykerTest\Shared\Testify\Helper\ConfigHelper + - \SprykerTest\Shared\Testify\Helper\LocatorHelper: + coreNamespaces: + - 'Spryker' + - 'SprykerEco' + - \SprykerTest\Shared\Testify\Helper\DependencyHelper + - \SprykerTest\Shared\Testify\Helper\DataCleanupHelper + - \SprykerTest\Shared\Propel\Helper\TransactionHelper + - \SprykerTest\Zed\Testify\Helper\Business\DependencyProviderHelper + - \SprykerTest\Zed\Testify\Helper\Business\BusinessHelper + - \SprykerTest\Shared\User\Helper\UserDataHelper