From c86ced59704bb9da51f9257495b2162be7e97564 Mon Sep 17 00:00:00 2001 From: Nazarn96 Date: Tue, 24 Sep 2019 17:00:01 +0300 Subject: [PATCH 1/7] Fix: Error when loading grid after logout on adobe side --- AdobeStockClient/Model/Client.php | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/AdobeStockClient/Model/Client.php b/AdobeStockClient/Model/Client.php index 098dd8c59ff6..8260cad366f1 100644 --- a/AdobeStockClient/Model/Client.php +++ b/AdobeStockClient/Model/Client.php @@ -227,8 +227,8 @@ public function getFullEntitlementQuota(): UserQuotaInterface $quota = $this->getLicenseInfo(0)->getEntitlement()->getFullEntitlementQuota(); /** @var UserQuotaInterface $userQuota */ $userQuota = $this->userQuotaFactory->create(); - $userQuota->setImages((int) $quota->standard_credits_quota); - $userQuota->setCredits((int) $quota->premium_credits_quota); + $userQuota->setImages((int)$quota->standard_credits_quota); + $userQuota->setCredits((int)$quota->premium_credits_quota); return $userQuota; } @@ -318,11 +318,11 @@ private function getResultColumns(): array private function getConnection(string $key = null): AdobeStock { try { - $apiKey = !empty($key) ? $key : (string) $this->imsConfig->getApiKey(); + $apiKey = !empty($key) ? $key : (string)$this->imsConfig->getApiKey(); return $this->connectionFactory->create( $apiKey, - (string) $this->clientConfig->getProductName(), - (string) $this->clientConfig->getTargetEnvironment() + (string)$this->clientConfig->getProductName(), + (string)$this->clientConfig->getTargetEnvironment() ); } catch (Exception $exception) { $message = __( @@ -334,19 +334,26 @@ private function getConnection(string $key = null): AdobeStock } /** - * Retrieve an access token for current user + * Checks if Access token valid and returns result. * * @return string|null + * @throws \Magento\Framework\Exception\CouldNotSaveException */ private function getAccessToken() { try { - return $this->userProfileRepository->getByUserId( - (int)$this->userContext->getUserId() - )->getAccessToken(); - } catch (NoSuchEntityException $exception) { - return null; + $userProfile = $this->userProfileRepository->getByUserId((int)$this->userContext->getUserId()); + $accessToken = $userProfile->getAccessToken(); + if ($accessToken) { + $this->getConnection()->getContentInfo($this->getLicenseRequest(0), $accessToken); + return $accessToken; + } + } catch (Exception $e) { + $userProfile->setAccessToken(''); + $userProfile->setRefreshToken(''); + $this->userProfileRepository->save($userProfile); } + return null; } /** From 804d6d0fa1fd735e2851f64acc406292071da3af Mon Sep 17 00:00:00 2001 From: Nazarn96 Date: Mon, 30 Sep 2019 16:46:46 +0300 Subject: [PATCH 2/7] test commit --- AdobeStockClient/Model/Client.php | 1 - 1 file changed, 1 deletion(-) diff --git a/AdobeStockClient/Model/Client.php b/AdobeStockClient/Model/Client.php index 8260cad366f1..5f85a468b624 100644 --- a/AdobeStockClient/Model/Client.php +++ b/AdobeStockClient/Model/Client.php @@ -369,7 +369,6 @@ public function testConnection(string $apiKey = null): bool $searchParams = new SearchParameters(); $searchRequest = new SearchFilesRequest(); $resultColumnArray = []; - $resultColumnArray[] = 'nb_results'; $searchRequest->setLocale('en_GB'); From 062b1e877f7df3b05f37fd8ca27c98ab1e28df8d Mon Sep 17 00:00:00 2001 From: Nazarn96 Date: Tue, 1 Oct 2019 13:59:59 +0300 Subject: [PATCH 3/7] Fix failing integration test. --- .../Test/Integration/Model/ClientTest.php | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/AdobeStockClient/Test/Integration/Model/ClientTest.php b/AdobeStockClient/Test/Integration/Model/ClientTest.php index cfa2aa4acbdc..638e463de63e 100644 --- a/AdobeStockClient/Test/Integration/Model/ClientTest.php +++ b/AdobeStockClient/Test/Integration/Model/ClientTest.php @@ -12,8 +12,10 @@ use AdobeStock\Api\Models\StockFile; use AdobeStock\Api\Response\SearchFiles as SearchFilesResponse; use AdobeStock\Api\Request\SearchFiles as SearchFilesRequest; +use Magento\AdobeImsApi\Api\Data\UserProfileInterface; use Magento\AdobeStockClient\Model\Client; use Magento\AdobeStockClient\Model\ConnectionFactory; +use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\Search\SearchCriteriaBuilder; use Magento\Framework\Api\Search\SearchResultInterface; @@ -22,6 +24,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Magento\Framework\Api\Search\SearchCriteriaInterface; +use Magento\AdobeImsApi\Api\UserProfileRepositoryInterface; /** * Test client for communication to Adobe Stock API. @@ -38,6 +41,16 @@ class ClientTest extends TestCase */ private $connection; + /** + * @var MockObject $userContextMock + */ + private $userContextMock; + + /** + * @var MockObject $userProfile + */ + private $userProfile; + /** * Prepare objects. */ @@ -54,10 +67,14 @@ protected function setUp(): void $connectionFactory->expects($this->once()) ->method('create') ->willReturn($this->connection); + $this->userContextMock = $this->createMock(\Magento\Authorization\Model\UserContextInterface::class); + $this->userProfile = $this->createMock(UserProfileRepositoryInterface::class); $this->client = Bootstrap::getObjectManager()->create( Client::class, [ - 'connectionFactory' => $connectionFactory + 'connectionFactory' => $connectionFactory, + 'userProfileRepository' => $this->userProfile, + 'userContext' => $this->userContextMock, ] ); } @@ -81,7 +98,9 @@ public function testSearch(): void $response->expects($this->once()) ->method('getNbResults') ->willReturn(3); - + $userProfileInterface = $this->createMock(UserProfileInterface::class); + $this->userProfile->expects($this->once())->method('getByUserId')->willReturn($userProfileInterface); + $this->userContextMock->expects($this->once())->method('getUserId')->willReturn(1); $this->connection->expects($this->once()) ->method('searchFilesInitialize') ->with( From 14e34ad3bbf0b563cc78470bc88c177f1bcfd68b Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Wed, 9 Oct 2019 17:24:59 +0100 Subject: [PATCH 4/7] magento/adobe-stock-integration#473: Applied solution globally and extracted services to Adobe IMS --- AdobeIms/Model/FlushUserTokens.php | 60 ++++ AdobeIms/Model/GetAccessToken.php | 57 ++++ AdobeIms/Model/LogOut.php | 11 +- AdobeIms/etc/di.xml | 2 + AdobeImsApi/Api/FlushUserTokensInterface.php | 24 ++ AdobeImsApi/Api/GetAccessTokenInterface.php | 24 ++ AdobeStockClient/Model/Client.php | 180 ++---------- AdobeStockClient/Model/Connection.php | 268 ++++++++++++++++++ AdobeStockClient/Model/ConnectionFactory.php | 11 +- .../Test/Integration/Model/ClientTest.php | 36 +-- AdobeStockClientApi/Api/ClientInterface.php | 7 +- .../Model/SignInConfigProvider.php | 23 +- 12 files changed, 504 insertions(+), 199 deletions(-) create mode 100644 AdobeIms/Model/FlushUserTokens.php create mode 100644 AdobeIms/Model/GetAccessToken.php create mode 100644 AdobeImsApi/Api/FlushUserTokensInterface.php create mode 100644 AdobeImsApi/Api/GetAccessTokenInterface.php create mode 100644 AdobeStockClient/Model/Connection.php diff --git a/AdobeIms/Model/FlushUserTokens.php b/AdobeIms/Model/FlushUserTokens.php new file mode 100644 index 000000000000..21f74cdb61a8 --- /dev/null +++ b/AdobeIms/Model/FlushUserTokens.php @@ -0,0 +1,60 @@ +userContext = $userContext; + $this->userProfileRepository = $userProfileRepository; + } + + /** + * @inheritdoc + */ + public function execute(int $adminUserId = null): void + { + try { + if ($adminUserId === null) { + $adminUserId = (int) $this->userContext->getUserId(); + } + + $userProfile = $this->userProfileRepository->getByUserId($adminUserId); + $userProfile->setAccessToken(''); + $userProfile->setRefreshToken(''); + $this->userProfileRepository->save($userProfile); + } catch (\Exception $e) { + // User profile and tokens are not present in the system + } + } +} diff --git a/AdobeIms/Model/GetAccessToken.php b/AdobeIms/Model/GetAccessToken.php new file mode 100644 index 000000000000..271535dc9603 --- /dev/null +++ b/AdobeIms/Model/GetAccessToken.php @@ -0,0 +1,57 @@ +userContext = $userContext; + $this->userProfileRepository = $userProfileRepository; + } + + /** + * @inheritdoc + */ + public function execute(int $adminUserId = null): ?string + { + try { + if ($adminUserId === null) { + $adminUserId = (int) $this->userContext->getUserId(); + } + return $this->userProfileRepository->getByUserId($adminUserId)->getAccessToken(); + } catch (NoSuchEntityException $exception) { + return null; + } + } +} diff --git a/AdobeIms/Model/LogOut.php b/AdobeIms/Model/LogOut.php index 486ce5c83163..3b2db99ba466 100644 --- a/AdobeIms/Model/LogOut.php +++ b/AdobeIms/Model/LogOut.php @@ -8,6 +8,7 @@ use Magento\AdobeImsApi\Api\LogOutInterface; use Magento\AdobeImsApi\Api\Data\ConfigInterface; use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\HTTP\Client\CurlFactory; use Psr\Log\LoggerInterface; @@ -75,7 +76,15 @@ public function __construct( public function execute() : bool { try { - $userProfile = $this->userProfileRepository->getByUserId((int)$this->userContext->getUserId()); + try { + $userProfile = $this->userProfileRepository->getByUserId((int)$this->userContext->getUserId()); + } catch (NoSuchEntityException $exception) { + return true; + } + + if (empty($userProfile->getAccessToken()) && empty($userProfile->getRefreshToken())) { + return true; + } $curl = $this->curlFactory->create(); $curl->addHeader('Content-Type', 'application/x-www-form-urlencoded'); diff --git a/AdobeIms/etc/di.xml b/AdobeIms/etc/di.xml index da69fa18f1b7..5639601d57c5 100644 --- a/AdobeIms/etc/di.xml +++ b/AdobeIms/etc/di.xml @@ -14,4 +14,6 @@ + + diff --git a/AdobeImsApi/Api/FlushUserTokensInterface.php b/AdobeImsApi/Api/FlushUserTokensInterface.php new file mode 100644 index 000000000000..778f44e33d7d --- /dev/null +++ b/AdobeImsApi/Api/FlushUserTokensInterface.php @@ -0,0 +1,24 @@ +clientConfig = $clientConfig; - $this->imsConfig = $imsConfig; + $this->config = $config; + $this->connection = $connection; $this->searchResultFactory = $searchResultFactory; $this->searchParametersProvider = $searchParametersProvider; $this->localeResolver = $localeResolver; - $this->connectionFactory = $connectionFactory; $this->licenseRequestFactory = $licenseRequestFactory; $this->logger = $logger; - $this->userProfileRepository = $userProfileRepository; - $this->userContext = $userContext; $this->userQuotaFactory = $userQuotaFactory; $this->stockFileToDocument = $stockFileToDocument; $this->licenseConfirmationFactory = $licenseConfirmationFactory; @@ -164,20 +137,14 @@ public function search(SearchCriteriaInterface $searchCriteria): SearchResultInt $connection = $this->getConnection(); try { - $connection->searchFilesInitialize( - $this->getSearchRequest($searchCriteria), - $this->getAccessToken() - ); + $connection->searchFilesInitialize($this->getSearchRequest($searchCriteria)); $response = $connection->getNextResponse(); /** @var StockFile $file */ foreach ($response->getFiles() as $file) { $items[] = $this->stockFileToDocument->convert($file); } $totalCount = $response->getNbResults(); - } catch (Exception $exception) { - if (strpos($exception->getMessage(), 'Api Key is invalid') !== false) { - throw new AuthenticationException(__($exception->getMessage()), $exception, $exception->getCode()); - } + } catch (IntegrationException $exception) { $this->logger->critical($exception->getMessage()); } @@ -201,7 +168,7 @@ private function getLicenseRequest(int $contentId): LicenseRequest /** @var LicenseRequest $licenseRequest */ $licenseRequest = $this->licenseRequestFactory->create(); $licenseRequest->setContentId($contentId) - ->setLocale($this->clientConfig->getLocale()) + ->setLocale($this->config->getLocale()) ->setLicenseState('STANDARD'); return $licenseRequest; @@ -217,7 +184,7 @@ private function getLicenseRequest(int $contentId): LicenseRequest */ private function getLicenseInfo(int $contentId): License { - return $this->getConnection()->getMemberProfile($this->getLicenseRequest($contentId), $this->getAccessToken()); + return $this->getConnection()->getMemberProfile($this->getLicenseRequest($contentId)); } /** @@ -250,31 +217,19 @@ public function getLicenseConfirmation(int $contentId): LicenseConfirmationInter } /** - * Performs image license request to Adobe Stock APi - * - * @param int $contentId - * @throws IntegrationException - * @throws StockApi + * @inheritdoc */ public function licenseImage(int $contentId): void { - $licenseRequest = $this->getLicenseRequest($contentId); - $this->getConnection()->getContentLicense($licenseRequest, $this->getAccessToken()); + $this->getConnection()->getContentLicense($this->getLicenseRequest($contentId)); } /** - * Returns download URL for a licensed image - * - * @param int $contentId - * @return string - * @throws IntegrationException - * @throws \AdobeStock\Api\Exception\StockApi + * @inheritdoc */ public function getImageDownloadUrl(int $contentId): string { - $licenseRequest = $this->getLicenseRequest($contentId); - - return $this->getConnection()->downloadAssetUrl($licenseRequest, $this->getAccessToken()); + return $this->getConnection()->downloadAssetUrl($this->getLicenseRequest($contentId)); } /** @@ -305,7 +260,7 @@ private function getResultColumns(): array { $resultsColumns = Constants::getResultColumns(); $resultColumnArray = []; - foreach ($this->clientConfig->getSearchResultFields() as $field) { + foreach ($this->config->getSearchResultFields() as $field) { if (!isset($resultsColumns[$field])) { $message = __('Cannot retrieve the field %1. It\'s not available in Adobe Stock SDK', $field); $this->logger->critical($message); @@ -318,96 +273,17 @@ private function getResultColumns(): array /** * Initialize connection to the Adobe Stock service. - * - * @param string $key - * - * @return AdobeStock - * @throws IntegrationException - */ - private function getConnection(string $key = null): AdobeStock - { - try { - $apiKey = !empty($key) ? $key : (string)$this->imsConfig->getApiKey(); - return $this->connectionFactory->create( - $apiKey, - (string)$this->clientConfig->getProductName(), - (string)$this->clientConfig->getTargetEnvironment() - ); - } catch (Exception $exception) { - $message = __( - 'An error occurred during Adobe Stock connection initialization: %error_message', - ['error_message' => $exception->getMessage()] - ); - $this->processException($message, $exception); - } - } - - /** - * Checks if Access token valid and returns result. - * - * @return string|null - * @throws \Magento\Framework\Exception\CouldNotSaveException - */ - private function getAccessToken() - { - try { - $userProfile = $this->userProfileRepository->getByUserId((int)$this->userContext->getUserId()); - $accessToken = $userProfile->getAccessToken(); - if ($accessToken) { - $this->getConnection()->getContentInfo($this->getLicenseRequest(0), $accessToken); - return $accessToken; - } - } catch (Exception $e) { - $userProfile->setAccessToken(''); - $userProfile->setRefreshToken(''); - $this->userProfileRepository->save($userProfile); - } - return null; - } - - /** - * Test connection to Adobe Stock API - * - * @param string $apiKey - * - * @return bool */ - public function testConnection(string $apiKey = null): bool + private function getConnection(): Connection { - try { - $searchParams = new SearchParameters(); - $searchRequest = new SearchFilesRequest(); - $resultColumnArray = []; - $resultColumnArray[] = 'nb_results'; - - $searchRequest->setLocale('en_GB'); - $searchRequest->setSearchParams($searchParams); - $searchRequest->setResultColumns($resultColumnArray); - - $client = $this->getConnection($apiKey); - $client->searchFilesInitialize($searchRequest, $this->getAccessToken()); - - return (bool)$client->getNextResponse()->nb_results; - } catch (Exception $exception) { - $message = __( - 'An error occurred during Adobe Stock API connection test: %error_message', - ['error_message' => $exception->getMessage()] - ); - $this->logger->notice($message->render()); - return false; - } + return $this->connection; } /** - * Handle SDK Exception and throw Magento exception instead - * - * @param Phrase $message - * @param Exception $exception - * @throws IntegrationException + * @inheritdoc */ - private function processException(Phrase $message, Exception $exception) + public function testConnection(string $apiKey): bool { - $this->logger->critical($message->render()); - throw new IntegrationException($message, $exception, $exception->getCode()); + return $this->getConnection()->testApiKey($apiKey); } } diff --git a/AdobeStockClient/Model/Connection.php b/AdobeStockClient/Model/Connection.php new file mode 100644 index 000000000000..a897a4e744d8 --- /dev/null +++ b/AdobeStockClient/Model/Connection.php @@ -0,0 +1,268 @@ +clientConfig = $clientConfig; + $this->connectionFactory = $connectionFactory; + $this->imsConfig = $imsConfig; + $this->log = $logger; + $this->getAccessToken = $getAccessToken; + $this->flushUserTokens = $flushUserTokens; + $this->httpClient = $httpClient; + } + + /** + * Create new SDK connection instance + * + * @param string|null $apiKey + * @return AdobeStock + */ + private function getConnection(string $apiKey = null): AdobeStock + { + if (!$this->connection) { + $this->connection = $this->connectionFactory->create( + $apiKey ?? $this->imsConfig->getApiKey(), + $this->clientConfig->getProductName(), + $this->clientConfig->getTargetEnvironment(), + $this->httpClient + ); + } + return $this->connection; + } + + /** + * Checks if Access token valid and returns result. + * + * @return string|null + */ + private function getAccessToken(): string + { + return $this->getAccessToken->execute(); + } + + /** + * @param \Exception $exception + * @throws AuthenticationException + * @throws AuthorizationException + * @throws IntegrationException + */ + private function handleException(\Exception $exception, string $message): void + { + if (strpos($exception->getMessage(), 'Api Key is invalid') !== false) { + throw new AuthenticationException( __('Adobe API Key is invalid!')); + } + if (strpos($exception->getMessage(), 'Oauth token is not valid') !== false) { + $this->flushUserTokens->execute(); + throw new AuthorizationException( __('Adobe API login has expired!')); + } + $phrase = __( + $message . ': %error_message', + ['error_message' => $exception->getMessage()] + ); + throw new IntegrationException($phrase, $exception, $exception->getCode()); + } + + /** + * Test if the connection to Adobe Stock API can be established with the given API key + * + * @param string $apiKey + * @return bool + */ + public function testApiKey(string $apiKey): bool + { + try { + $searchParams = new SearchParameters(); + $searchRequest = new SearchFilesRequest(); + $resultColumnArray = []; + $resultColumnArray[] = 'nb_results'; + + $searchRequest->setLocale('en_GB'); + $searchRequest->setSearchParams($searchParams); + $searchRequest->setResultColumns($resultColumnArray); + + $client = $this->getConnection($apiKey); + $client->searchFilesInitialize($searchRequest); + + return (bool)$client->getNextResponse()->nb_results; + } catch (Exception $exception) { + return false; + } + } + + /** + * Method to initialize search files. + * + * @param SearchFilesRequest $request + * @return $this + * @throws AuthenticationException + * @throws AuthorizationException + * @throws IntegrationException + */ + public function searchFilesInitialize(SearchFilesRequest $request): self + { + try { + $this->getConnection()->searchFilesInitialize($request, $this->getAccessToken()); + return $this; + } catch (\Exception $exception) { + $this->handleException($exception, 'Failed to initialize Adobe Stock search files request'); + } + } + + /** + * Get the next search files response page. + * + * @return SearchFilesResponse + * @throws AuthenticationException + * @throws AuthorizationException + * @throws IntegrationException + */ + public function getNextResponse(): SearchFilesResponse + { + try { + return $this->getConnection()->getNextResponse(); + } catch (\Exception $exception) { + $this->handleException($exception, 'Failed to retrieve Adobe Stock search files results'); + } + } + + /** + * Get the licensing capabilities for a user. + * + * @param LicenseRequest $request + * @return LicenseResponse + * @throws AuthenticationException + * @throws AuthorizationException + * @throws IntegrationException + */ + public function getMemberProfile(LicenseRequest $request): LicenseResponse + { + try { + return $this->getConnection()->getMemberProfile($request, $this->getAccessToken()); + } catch (\Exception $exception) { + $this->handleException($exception, 'Failed to retrieve Adobe Stock member profile'); + } + } + + /** + * Requests a license for an asset for a specific user. + * + * @param LicenseRequest $request + * @return LicenseResponse + * @throws AuthenticationException + * @throws AuthorizationException + * @throws IntegrationException + */ + public function getContentLicense(LicenseRequest $request): LicenseResponse + { + try { + return $this->getConnection()->getContentLicense($request, $this->getAccessToken()); + } catch (\Exception $exception) { + $this->handleException($exception, 'Failed to retrieve Adobe Stock content license'); + } + } + + /** + * Provide the url of the asset if it is already licensed. + * + * @param LicenseRequest $request + * @return string + * @throws AuthenticationException + * @throws AuthorizationException + * @throws IntegrationException + */ + public function downloadAssetUrl(LicenseRequest $request): string + { + try { + return $this->getConnection()->downloadAssetUrl($request, $this->getAccessToken()); + } catch (\Exception $exception) { + $this->handleException($exception, 'Failed to retrieve Adobe Stock asset download URL'); + } + } +} diff --git a/AdobeStockClient/Model/ConnectionFactory.php b/AdobeStockClient/Model/ConnectionFactory.php index c91fc2de27e9..1b895c59278d 100644 --- a/AdobeStockClient/Model/ConnectionFactory.php +++ b/AdobeStockClient/Model/ConnectionFactory.php @@ -9,6 +9,7 @@ namespace Magento\AdobeStockClient\Model; use AdobeStock\Api\Client\AdobeStock; +use AdobeStock\Api\Client\Http\HttpInterface; /** * Class ConnectionFactory @@ -23,8 +24,12 @@ class ConnectionFactory * @param string $targetEnvironment * @return AdobeStock */ - public function create(string $apiKey, string $productName, string $targetEnvironment): AdobeStock - { - return new AdobeStock($apiKey, $productName, $targetEnvironment); + public function create( + string $apiKey, + string $productName, + string $targetEnvironment, + HttpInterface $httpClient = null + ): AdobeStock { + return new AdobeStock($apiKey, $productName, $targetEnvironment, $httpClient); } } diff --git a/AdobeStockClient/Test/Integration/Model/ClientTest.php b/AdobeStockClient/Test/Integration/Model/ClientTest.php index 638e463de63e..2cc2811a53a1 100644 --- a/AdobeStockClient/Test/Integration/Model/ClientTest.php +++ b/AdobeStockClient/Test/Integration/Model/ClientTest.php @@ -8,14 +8,11 @@ namespace Magento\AdobeStockClient\Test\Integration\Model; -use AdobeStock\Api\Client\AdobeStock; use AdobeStock\Api\Models\StockFile; use AdobeStock\Api\Response\SearchFiles as SearchFilesResponse; use AdobeStock\Api\Request\SearchFiles as SearchFilesRequest; -use Magento\AdobeImsApi\Api\Data\UserProfileInterface; use Magento\AdobeStockClient\Model\Client; -use Magento\AdobeStockClient\Model\ConnectionFactory; -use Magento\Authorization\Model\UserContextInterface; +use Magento\AdobeStockClient\Model\Connection; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\Search\SearchCriteriaBuilder; use Magento\Framework\Api\Search\SearchResultInterface; @@ -24,7 +21,6 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Magento\Framework\Api\Search\SearchCriteriaInterface; -use Magento\AdobeImsApi\Api\UserProfileRepositoryInterface; /** * Test client for communication to Adobe Stock API. @@ -37,44 +33,23 @@ class ClientTest extends TestCase private $client; /** - * @var AdobeStock|MockObject + * @var Connection|MockObject */ private $connection; - /** - * @var MockObject $userContextMock - */ - private $userContextMock; - - /** - * @var MockObject $userProfile - */ - private $userProfile; - /** * Prepare objects. */ protected function setUp(): void { - $this->connection = $this->getMockBuilder(AdobeStock::class) + $this->connection = $this->getMockBuilder(Connection::class) ->setMethods(['searchFilesInitialize', 'getNextResponse']) ->disableOriginalConstructor() ->getMock(); - $connectionFactory = $this->getMockBuilder(ConnectionFactory::class) - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $connectionFactory->expects($this->once()) - ->method('create') - ->willReturn($this->connection); - $this->userContextMock = $this->createMock(\Magento\Authorization\Model\UserContextInterface::class); - $this->userProfile = $this->createMock(UserProfileRepositoryInterface::class); $this->client = Bootstrap::getObjectManager()->create( Client::class, [ - 'connectionFactory' => $connectionFactory, - 'userProfileRepository' => $this->userProfile, - 'userContext' => $this->userContextMock, + 'connection' => $this->connection ] ); } @@ -98,9 +73,6 @@ public function testSearch(): void $response->expects($this->once()) ->method('getNbResults') ->willReturn(3); - $userProfileInterface = $this->createMock(UserProfileInterface::class); - $this->userProfile->expects($this->once())->method('getByUserId')->willReturn($userProfileInterface); - $this->userContextMock->expects($this->once())->method('getUserId')->willReturn(1); $this->connection->expects($this->once()) ->method('searchFilesInitialize') ->with( diff --git a/AdobeStockClientApi/Api/ClientInterface.php b/AdobeStockClientApi/Api/ClientInterface.php index 9dba2a39c401..05d0f0a2bfdb 100644 --- a/AdobeStockClientApi/Api/ClientInterface.php +++ b/AdobeStockClientApi/Api/ClientInterface.php @@ -44,11 +44,10 @@ public function getLicenseConfirmation(int $contentId): LicenseConfirmationInter /** * Perform a basic request to Adobe Stock API to check network connection, API key, etc. * - * @param string|null $apiKey - * + * @param string $apiKey * @return bool */ - public function testConnection(string $apiKey = null): bool; + public function testConnection(string $apiKey): bool; /** * Invokes licensing image operation via Adobe Stock API @@ -62,7 +61,7 @@ public function licenseImage(int $contentId): void; * Returns download URL for a licensed image * * @param int $contentId - * @return mixed + * @return string */ public function getImageDownloadUrl(int $contentId): string; } diff --git a/AdobeStockImageAdminUi/Model/SignInConfigProvider.php b/AdobeStockImageAdminUi/Model/SignInConfigProvider.php index 9c0ee4e11c05..9637925e5cf1 100644 --- a/AdobeStockImageAdminUi/Model/SignInConfigProvider.php +++ b/AdobeStockImageAdminUi/Model/SignInConfigProvider.php @@ -10,6 +10,8 @@ use Magento\AdobeImsApi\Api\ConfigProviderInterface; use Magento\AdobeImsApi\Api\UserAuthorizedInterface; use Magento\AdobeStockClientApi\Api\ClientInterface; +use Magento\Framework\Exception\AuthenticationException; +use Magento\Framework\Exception\AuthorizationException; use Magento\Framework\UrlInterface; /** @@ -68,16 +70,23 @@ public function get(): array */ private function getUserQuota(): array { + $defaultQuota = [ + 'images' => 0, + 'credits' => 0 + ]; if (!$this->userAuthorized->execute()) { + return $defaultQuota; + } + try { + $quota = $this->client->getQuota(); return [ - 'images' => 0, - 'credits' => 0 + 'images' => $quota->getImages(), + 'credits' => $quota->getCredits() ]; + } catch (AuthenticationException $exception) { + return $defaultQuota; + } catch (AuthorizationException $exception) { + return $defaultQuota; } - $quota = $this->client->getQuota(); - return [ - 'images' => $quota->getImages(), - 'credits' => $quota->getCredits() - ]; } } From b9c0fff1bd4176e505b5f7f32b2d3d15dc85e8b3 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Wed, 9 Oct 2019 17:49:12 +0100 Subject: [PATCH 5/7] magento/adobe-stock-integration#473: Fixed tests --- AdobeIms/Model/LogOut.php | 6 ++++-- AdobeStockClient/Model/Connection.php | 9 ++++++--- AdobeStockClient/Test/Integration/Model/ClientTest.php | 3 +-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/AdobeIms/Model/LogOut.php b/AdobeIms/Model/LogOut.php index 3b2db99ba466..35411cb32c56 100644 --- a/AdobeIms/Model/LogOut.php +++ b/AdobeIms/Model/LogOut.php @@ -82,14 +82,16 @@ public function execute() : bool return true; } - if (empty($userProfile->getAccessToken()) && empty($userProfile->getRefreshToken())) { + $accessToken = $userProfile->getAccessToken(); + + if (empty($accessToken)) { return true; } $curl = $this->curlFactory->create(); $curl->addHeader('Content-Type', 'application/x-www-form-urlencoded'); $curl->addHeader('cache-control', 'no-cache'); - $curl->get($this->config->getLogoutUrl($userProfile->getAccessToken())); + $curl->get($this->config->getLogoutUrl($accessToken)); if ($curl->getStatus() === self::HTTP_FOUND) { $userProfile->setAccessToken(''); diff --git a/AdobeStockClient/Model/Connection.php b/AdobeStockClient/Model/Connection.php index a897a4e744d8..5232275d76aa 100644 --- a/AdobeStockClient/Model/Connection.php +++ b/AdobeStockClient/Model/Connection.php @@ -14,7 +14,6 @@ use AdobeStock\Api\Response\License as LicenseResponse; use AdobeStock\Api\Request\SearchFiles as SearchFilesRequest; use AdobeStock\Api\Response\SearchFiles as SearchFilesResponse; -use Exception; use Magento\AdobeImsApi\Api\FlushUserTokensInterface; use Magento\AdobeImsApi\Api\GetAccessTokenInterface; use Magento\AdobeImsApi\Api\Data\ConfigInterface as ImsConfig; @@ -25,6 +24,7 @@ use Magento\Framework\Exception\IntegrationException; use Magento\Framework\Exception\NoSuchEntityException; use Psr\Log\LoggerInterface; +use Exception; /** * Adapter for Adobe SDK @@ -128,12 +128,15 @@ private function getAccessToken(): string } /** - * @param \Exception $exception + * Handle Adobe Stock SDK exception + * + * @param Exception $exception + * @param string $message * @throws AuthenticationException * @throws AuthorizationException * @throws IntegrationException */ - private function handleException(\Exception $exception, string $message): void + private function handleException(Exception $exception, string $message): void { if (strpos($exception->getMessage(), 'Api Key is invalid') !== false) { throw new AuthenticationException( __('Adobe API Key is invalid!')); diff --git a/AdobeStockClient/Test/Integration/Model/ClientTest.php b/AdobeStockClient/Test/Integration/Model/ClientTest.php index 2cc2811a53a1..53412639d8e8 100644 --- a/AdobeStockClient/Test/Integration/Model/ClientTest.php +++ b/AdobeStockClient/Test/Integration/Model/ClientTest.php @@ -83,8 +83,7 @@ function (SearchFilesRequest $searchFiles) use ($words) { && in_array('nb_results', $searchFiles->getResultColumns()) && $searchFiles->getSearchParams()->getWords() == $words; } - ), - null + ) ); $this->connection->expects($this->once()) ->method('getNextResponse') From 98290086febad1a2665dbdb4c9668324a6420b93 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Wed, 9 Oct 2019 17:50:00 +0100 Subject: [PATCH 6/7] magento/adobe-stock-integration#473: Fixed tests --- AdobeStockClient/Model/Connection.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/AdobeStockClient/Model/Connection.php b/AdobeStockClient/Model/Connection.php index 5232275d76aa..5f132b76e25f 100644 --- a/AdobeStockClient/Model/Connection.php +++ b/AdobeStockClient/Model/Connection.php @@ -24,7 +24,6 @@ use Magento\Framework\Exception\IntegrationException; use Magento\Framework\Exception\NoSuchEntityException; use Psr\Log\LoggerInterface; -use Exception; /** * Adapter for Adobe SDK @@ -130,20 +129,20 @@ private function getAccessToken(): string /** * Handle Adobe Stock SDK exception * - * @param Exception $exception + * @param \Exception $exception * @param string $message * @throws AuthenticationException * @throws AuthorizationException * @throws IntegrationException */ - private function handleException(Exception $exception, string $message): void + private function handleException(\Exception $exception, string $message): void { if (strpos($exception->getMessage(), 'Api Key is invalid') !== false) { - throw new AuthenticationException( __('Adobe API Key is invalid!')); + throw new AuthenticationException(__('Adobe API Key is invalid!')); } if (strpos($exception->getMessage(), 'Oauth token is not valid') !== false) { $this->flushUserTokens->execute(); - throw new AuthorizationException( __('Adobe API login has expired!')); + throw new AuthorizationException(__('Adobe API login has expired!')); } $phrase = __( $message . ': %error_message', From f2856beb1e3f97e6c4de9b54ccbf5de6191cf669 Mon Sep 17 00:00:00 2001 From: Sergii Ivashchenko Date: Wed, 9 Oct 2019 17:58:18 +0100 Subject: [PATCH 7/7] magento/adobe-stock-integration#473: Fixed static tests --- AdobeStockClient/Model/ConnectionFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/AdobeStockClient/Model/ConnectionFactory.php b/AdobeStockClient/Model/ConnectionFactory.php index 1b895c59278d..9dbcf47a7315 100644 --- a/AdobeStockClient/Model/ConnectionFactory.php +++ b/AdobeStockClient/Model/ConnectionFactory.php @@ -22,6 +22,7 @@ class ConnectionFactory * @param string $apiKey * @param string $productName * @param string $targetEnvironment + * @param HttpInterface|null $httpClient * @return AdobeStock */ public function create(