diff --git a/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Activate.php b/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Activate.php index 66f1778c9e356..b5731fc07bb07 100644 --- a/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Activate.php +++ b/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Activate.php @@ -6,13 +6,17 @@ namespace Magento\Analytics\Controller\Adminhtml\Subscription; +use Magento\Analytics\Model\Config\Backend\Enabled; use Magento\Analytics\Model\NotificationTime; -use Magento\Analytics\Model\Subscription; use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; +use Magento\Config\Model\Config\Source\Enabledisable; +use Magento\Config\Model\PreparedValueFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Controller\Result\Json; use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Model\ResourceModel\Db\AbstractDb; use Psr\Log\LoggerInterface; /** @@ -20,13 +24,6 @@ */ class Activate extends Action { - /** - * Resource for managing subscription to Magento BI. - * - * @var Subscription - */ - private $subscription; - /** * @var LoggerInterface */ @@ -46,23 +43,36 @@ class Activate extends Action */ private $subscriptionApprovedField = 'analytics_subscription_checkbox'; + /** + * @var AbstractDb + */ + private $configValueResource; + + /** + * @var PreparedValueFactory + */ + private $preparedValueFactory; + /** * Activate constructor. * * @param Context $context - * @param Subscription $subscription * @param LoggerInterface $logger * @param NotificationTime $notificationTime + * @param AbstractDb $configValueResource + * @param PreparedValueFactory $preparedValueFactory */ public function __construct( Context $context, - Subscription $subscription, LoggerInterface $logger, - NotificationTime $notificationTime + NotificationTime $notificationTime, + AbstractDb $configValueResource, + PreparedValueFactory $preparedValueFactory ) { - $this->subscription = $subscription; $this->logger = $logger; $this->notificationTime = $notificationTime; + $this->configValueResource = $configValueResource; + $this->preparedValueFactory = $preparedValueFactory; parent::__construct($context); } @@ -85,7 +95,14 @@ public function execute() { try { if ($this->getRequest()->getParam($this->subscriptionApprovedField)) { - $this->subscription->enable(); + $configValue = $this->preparedValueFactory->create( + Enabled::XML_ENABLED_CONFIG_STRUCTURE_PATH, + Enabledisable::ENABLE_VALUE, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT + ); + + $this->configValueResource + ->save($configValue); } else { $this->notificationTime->unsetLastTimeNotificationValue(); } diff --git a/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Retry.php b/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Retry.php index c9f2aed21b6a2..122cf74123cc9 100644 --- a/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Retry.php +++ b/app/code/Magento/Analytics/Controller/Adminhtml/Subscription/Retry.php @@ -6,7 +6,7 @@ namespace Magento\Analytics\Controller\Adminhtml\Subscription; -use Magento\Analytics\Model\Subscription; +use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler; use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; use Magento\Framework\Controller\Result\Redirect; @@ -21,19 +21,19 @@ class Retry extends Action /** * Resource for managing subscription to Magento Analytics. * - * @var Subscription + * @var SubscriptionHandler */ - private $subscription; + private $subscriptionHandler; /** * @param Context $context - * @param Subscription $subscription + * @param SubscriptionHandler $subscriptionHandler */ public function __construct( Context $context, - Subscription $subscription + SubscriptionHandler $subscriptionHandler ) { - $this->subscription = $subscription; + $this->subscriptionHandler = $subscriptionHandler; parent::__construct($context); } @@ -58,7 +58,7 @@ public function execute() $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); try { $resultRedirect->setPath('adminhtml'); - $this->subscription->retry(); + $this->subscriptionHandler->processEnabled(); } catch (LocalizedException $e) { $this->getMessageManager()->addExceptionMessage($e, $e->getMessage()); } catch (\Exception $e) { diff --git a/app/code/Magento/Analytics/Model/Config/Backend/Enabled.php b/app/code/Magento/Analytics/Model/Config/Backend/Enabled.php index fd0bf970b92c9..ac97f2a843e61 100644 --- a/app/code/Magento/Analytics/Model/Config/Backend/Enabled.php +++ b/app/code/Magento/Analytics/Model/Config/Backend/Enabled.php @@ -20,6 +20,11 @@ */ class Enabled extends Value { + /** + * Path to field subscription enabled into config structure. + */ + const XML_ENABLED_CONFIG_STRUCTURE_PATH = 'analytics/general/enabled'; + /** * Service for processing of activation/deactivation MBI subscription. * diff --git a/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php b/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php index 71f2100a5cebc..d23f5a7c60d91 100644 --- a/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php +++ b/app/code/Magento/Analytics/Model/Config/Backend/Enabled/SubscriptionHandler.php @@ -8,8 +8,9 @@ use Magento\Analytics\Model\AnalyticsToken; use Magento\Analytics\Model\Config\Backend\CollectionTime; use Magento\Analytics\Model\NotificationTime; -use Magento\Framework\FlagManager; +use Magento\Framework\App\Config\ReinitableConfigInterface; use Magento\Framework\App\Config\Storage\WriterInterface; +use Magento\Framework\FlagManager; /** * Class for processing of activation/deactivation MBI subscription. @@ -61,22 +62,30 @@ class SubscriptionHandler */ private $notificationTime; + /** + * @var ReinitableConfigInterface + */ + private $reinitableConfig; + /** * @param WriterInterface $configWriter * @param FlagManager $flagManager * @param AnalyticsToken $analyticsToken * @param NotificationTime $notificationTime + * @param ReinitableConfigInterface $reinitableConfig */ public function __construct( WriterInterface $configWriter, FlagManager $flagManager, AnalyticsToken $analyticsToken, - NotificationTime $notificationTime + NotificationTime $notificationTime, + ReinitableConfigInterface $reinitableConfig ) { $this->configWriter = $configWriter; $this->flagManager = $flagManager; $this->analyticsToken = $analyticsToken; $this->notificationTime = $notificationTime; + $this->reinitableConfig = $reinitableConfig; } /** @@ -92,6 +101,7 @@ public function processEnabled() $this->setCronSchedule(); $this->setAttemptsFlag(); $this->notificationTime->unsetLastTimeNotificationValue(); + $this->reinitableConfig->reinit(); } return true; diff --git a/app/code/Magento/Analytics/Model/Connector/CommandInterface.php b/app/code/Magento/Analytics/Model/Connector/CommandInterface.php index 8fe26bcb94a03..7a8774fe3dba9 100644 --- a/app/code/Magento/Analytics/Model/Connector/CommandInterface.php +++ b/app/code/Magento/Analytics/Model/Connector/CommandInterface.php @@ -14,7 +14,8 @@ interface CommandInterface /** * Execute call to external service * Information about destination and arguments appears from config - * @return void + * + * @return bool */ public function execute(); } diff --git a/app/code/Magento/Analytics/Model/Connector/Http/Client/Curl.php b/app/code/Magento/Analytics/Model/Connector/Http/Client/Curl.php index 4d409db494ccf..c223bb1f3b07d 100644 --- a/app/code/Magento/Analytics/Model/Connector/Http/Client/Curl.php +++ b/app/code/Magento/Analytics/Model/Connector/Http/Client/Curl.php @@ -5,9 +5,10 @@ */ namespace Magento\Analytics\Model\Connector\Http\Client; -use Magento\Analytics\Model\Connector\Http\ResponseFactory; -use Magento\Framework\HTTP\Adapter\CurlFactory; +use Magento\Analytics\Model\Connector\Http\ConverterInterface; use Psr\Log\LoggerInterface; +use Magento\Framework\HTTP\Adapter\CurlFactory; +use Magento\Analytics\Model\Connector\Http\ResponseFactory; /** * A CURL HTTP client. @@ -16,11 +17,6 @@ */ class Curl implements \Magento\Analytics\Model\Connector\Http\ClientInterface { - /** - * @var LoggerInterface - */ - private $logger; - /** * @var CurlFactory */ @@ -31,46 +27,83 @@ class Curl implements \Magento\Analytics\Model\Connector\Http\ClientInterface */ private $responseFactory; + /** + * @var ConverterInterface + */ + private $converter; + + /** + * @var LoggerInterface + */ + private $logger; + /** * @param CurlFactory $curlFactory * @param ResponseFactory $responseFactory + * @param ConverterInterface $converter * @param LoggerInterface $logger */ public function __construct( CurlFactory $curlFactory, ResponseFactory $responseFactory, + ConverterInterface $converter, LoggerInterface $logger ) { $this->curlFactory = $curlFactory; $this->responseFactory = $responseFactory; + $this->converter = $converter; $this->logger = $logger; } /** * {@inheritdoc} */ - public function request($method, $url, $body = '', array $headers = [], $version = '1.1') + public function request($method, $url, array $body = [], array $headers = [], $version = '1.1') { - $curl = $this->curlFactory->create(); + $response = new \Zend_Http_Response(0, []); - $curl->write($method, $url, $version, $headers, $body); + try { + $curl = $this->curlFactory->create(); + $headers = $this->applyContentTypeHeaderFromConverter($headers); - $result = $curl->read(); + $curl->write($method, $url, $version, $headers, $this->converter->toBody($body)); - if ($curl->getErrno()) { - $this->logger->critical( - new \Exception( - sprintf( - 'MBI service CURL connection error #%s: %s', - $curl->getErrno(), - $curl->getError() + $result = $curl->read(); + + if ($curl->getErrno()) { + $this->logger->critical( + new \Exception( + sprintf( + 'MBI service CURL connection error #%s: %s', + $curl->getErrno(), + $curl->getError() + ) ) - ) - ); + ); + + return $response; + } - return false; + $response = $this->responseFactory->create($result); + } catch (\Exception $e) { + $this->logger->critical($e); + } + + return $response; + } + + /** + * @param array $headers + * + * @return array + */ + private function applyContentTypeHeaderFromConverter(array $headers) + { + $contentTypeHeaderKey = array_search($this->converter->getContentTypeHeader(), $headers); + if ($contentTypeHeaderKey === false) { + $headers[] = $this->converter->getContentTypeHeader(); } - return $this->responseFactory->create($result); + return $headers; } } diff --git a/app/code/Magento/Analytics/Model/Connector/Http/ClientInterface.php b/app/code/Magento/Analytics/Model/Connector/Http/ClientInterface.php index ed44bd220760b..a1e1f057684f6 100644 --- a/app/code/Magento/Analytics/Model/Connector/Http/ClientInterface.php +++ b/app/code/Magento/Analytics/Model/Connector/Http/ClientInterface.php @@ -19,11 +19,11 @@ interface ClientInterface * * @param string $method * @param string $url - * @param string $body + * @param array $body * @param array $headers * @param string $version * - * @return \Zend_Http_Response|bool + * @return \Zend_Http_Response */ - public function request($method, $url, $body = '', array $headers = [], $version = '1.1'); + public function request($method, $url, array $body = [], array $headers = [], $version = '1.1'); } diff --git a/app/code/Magento/Analytics/Model/Connector/Http/ConverterInterface.php b/app/code/Magento/Analytics/Model/Connector/Http/ConverterInterface.php new file mode 100644 index 0000000000000..a6ce85cadc62f --- /dev/null +++ b/app/code/Magento/Analytics/Model/Connector/Http/ConverterInterface.php @@ -0,0 +1,31 @@ +converter = $converter; + $this->responseHandlers = $responseHandlers; + } + + /** + * @param \Zend_Http_Response $response + * + * @return bool|string + */ + public function getResult(\Zend_Http_Response $response) + { + $result = false; + $responseBody = $this->converter->fromBody($response->getBody()); + if (array_key_exists($response->getStatus(), $this->responseHandlers)) { + $result = $this->responseHandlers[$response->getStatus()]->handleResponse($responseBody); + } + + return $result; + } +} diff --git a/app/code/Magento/Analytics/Model/Connector/NotifyDataChangedCommand.php b/app/code/Magento/Analytics/Model/Connector/NotifyDataChangedCommand.php index 069f6b6d358a4..177ee64c82c5b 100644 --- a/app/code/Magento/Analytics/Model/Connector/NotifyDataChangedCommand.php +++ b/app/code/Magento/Analytics/Model/Connector/NotifyDataChangedCommand.php @@ -6,10 +6,11 @@ namespace Magento\Analytics\Model\Connector; use Magento\Analytics\Model\AnalyticsToken; -use Magento\Config\Model\Config; use Magento\Framework\HTTP\ZendClient; -use Magento\Store\Model\Store; +use Magento\Config\Model\Config; use Psr\Log\LoggerInterface; +use Magento\Store\Model\Store; +use Magento\Analytics\Model\Connector\Http\ResponseResolver; /** * Command notifies MBI about that data collection was finished. @@ -36,6 +37,11 @@ class NotifyDataChangedCommand implements CommandInterface */ private $config; + /** + * @var ResponseResolver + */ + private $responseResolver; + /** * @var LoggerInterface */ @@ -46,56 +52,44 @@ class NotifyDataChangedCommand implements CommandInterface * @param AnalyticsToken $analyticsToken * @param Http\ClientInterface $httpClient * @param Config $config + * @param ResponseResolver $responseResolver * @param LoggerInterface $logger */ public function __construct( AnalyticsToken $analyticsToken, Http\ClientInterface $httpClient, Config $config, + ResponseResolver $responseResolver, LoggerInterface $logger ) { $this->analyticsToken = $analyticsToken; $this->httpClient = $httpClient; $this->config = $config; + $this->responseResolver = $responseResolver; $this->logger = $logger; } /** * Notify MBI about that data collection was finished + * * @return bool */ public function execute() { $result = false; - try { - if ($this->analyticsToken->isTokenExist()) { - $this->httpClient->request( - ZendClient::POST, - $this->config->getConfigDataValue($this->notifyDataChangedUrlPath), - $this->getRequestJson(), - ['Content-Type: application/json'] - ); - $result = true; - } - } catch (\Exception $e) { - $this->logger->critical($e); + if ($this->analyticsToken->isTokenExist()) { + $response = $this->httpClient->request( + ZendClient::POST, + $this->config->getConfigDataValue($this->notifyDataChangedUrlPath), + [ + "access-token" => $this->analyticsToken->getToken(), + "url" => $this->config->getConfigDataValue( + Store::XML_PATH_SECURE_BASE_URL + ), + ] + ); + $result = $this->responseResolver->getResult($response); } return $result; } - - /** - * Prepares request data in JSON format. - * @return string - */ - private function getRequestJson() - { - return json_encode( - [ - "access-token" => $this->analyticsToken->getToken(), - "url" => $this->config->getConfigDataValue( - Store::XML_PATH_SECURE_BASE_URL - ), - ] - ); - } } diff --git a/app/code/Magento/Analytics/Model/Connector/OTPRequest.php b/app/code/Magento/Analytics/Model/Connector/OTPRequest.php index f4261ed2833f9..dfa283e10d070 100644 --- a/app/code/Magento/Analytics/Model/Connector/OTPRequest.php +++ b/app/code/Magento/Analytics/Model/Connector/OTPRequest.php @@ -6,11 +6,11 @@ namespace Magento\Analytics\Model\Connector; use Magento\Analytics\Model\AnalyticsToken; +use Magento\Analytics\Model\Connector\Http\ResponseResolver; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\HTTP\ZendClient; use Magento\Store\Model\Store; use Psr\Log\LoggerInterface; -use Zend_Http_Response as HttpResponse; /** * Representation of an 'OTP' request. @@ -44,6 +44,11 @@ class OTPRequest */ private $config; + /** + * @var ResponseResolver + */ + private $responseResolver; + /** * Path to the configuration value which contains * an URL that provides an OTP. @@ -56,17 +61,20 @@ class OTPRequest * @param AnalyticsToken $analyticsToken * @param Http\ClientInterface $httpClient * @param ScopeConfigInterface $config + * @param ResponseResolver $responseResolver * @param LoggerInterface $logger */ public function __construct( AnalyticsToken $analyticsToken, Http\ClientInterface $httpClient, ScopeConfigInterface $config, + ResponseResolver $responseResolver, LoggerInterface $logger ) { $this->analyticsToken = $analyticsToken; $this->httpClient = $httpClient; $this->config = $config; + $this->responseResolver = $responseResolver; $this->logger = $logger; } @@ -79,70 +87,29 @@ public function __construct( */ public function call() { - $otp = false; + $result = false; if ($this->analyticsToken->isTokenExist()) { - try { - $response = $this->httpClient->request( - ZendClient::POST, - $this->config->getValue($this->otpUrlConfigPath), - $this->getRequestJson(), - ['Content-Type: application/json'] + $response = $this->httpClient->request( + ZendClient::POST, + $this->config->getValue($this->otpUrlConfigPath), + [ + "access-token" => $this->analyticsToken->getToken(), + "url" => $this->config->getValue(Store::XML_PATH_SECURE_BASE_URL), + ] + ); + + $result = $this->responseResolver->getResult($response); + if (!$result) { + $this->logger->warning( + sprintf( + 'Obtaining of an OTP from the MBI service has been failed: %s', + !empty($response->getBody()) ? $response->getBody() : 'Response body is empty.' + ) ); - - if ($response) { - $otp = $this->extractOtp($response); - - if (!$otp) { - $this->logger->warning( - sprintf( - 'Obtaining of an OTP from the MBI service has been failed: %s', - !empty($response->getBody()) ? $response->getBody() : 'Response body is empty.' - ) - ); - } - } - } catch (\Exception $e) { - $this->logger->critical($e); } } - return $otp; - } - - /** - * Prepares request data in JSON format. - * - * @return string - */ - private function getRequestJson() - { - return json_encode( - [ - "access-token" => $this->analyticsToken->getToken(), - "url" => $this->config->getValue(Store::XML_PATH_SECURE_BASE_URL), - ] - ); - } - - /** - * Extracts an OTP from the response. - * - * Returns the OTP or FALSE if the OTP is not found. - * - * @param HttpResponse $response - * @return string|false - */ - private function extractOtp(HttpResponse $response) - { - $otp = false; - - if ($response->getStatus() === 201) { - $body = json_decode($response->getBody(), 1); - - $otp = !empty($body['otp']) ? $body['otp'] : false; - } - - return $otp; + return $result; } } diff --git a/app/code/Magento/Analytics/Model/Connector/ResponseHandler/OTP.php b/app/code/Magento/Analytics/Model/Connector/ResponseHandler/OTP.php new file mode 100644 index 0000000000000..d9a672e81f43d --- /dev/null +++ b/app/code/Magento/Analytics/Model/Connector/ResponseHandler/OTP.php @@ -0,0 +1,24 @@ +analyticsToken = $analyticsToken; + $this->subscriptionHandler = $subscriptionHandler; + $this->subscriptionStatusProvider = $subscriptionStatusProvider; + } + + /** + * @inheritdoc + */ + public function handleResponse(array $responseBody) + { + if ($this->subscriptionStatusProvider->getStatus() === SubscriptionStatusProvider::ENABLED) { + $this->analyticsToken->storeToken(null); + $this->subscriptionHandler->processEnabled(); + } + return false; + } +} diff --git a/app/code/Magento/Analytics/Model/Connector/ResponseHandler/SignUp.php b/app/code/Magento/Analytics/Model/Connector/ResponseHandler/SignUp.php new file mode 100644 index 0000000000000..b2261e418abc7 --- /dev/null +++ b/app/code/Magento/Analytics/Model/Connector/ResponseHandler/SignUp.php @@ -0,0 +1,51 @@ +analyticsToken = $analyticsToken; + $this->converter = $converter; + } + + /** + * @inheritdoc + */ + public function handleResponse(array $body) + { + if (isset($body['access-token']) && !empty($body['access-token'])) { + $this->analyticsToken->storeToken($body['access-token']); + return $body['access-token']; + } + + return false; + } +} diff --git a/app/code/Magento/Analytics/Model/Connector/ResponseHandler/Update.php b/app/code/Magento/Analytics/Model/Connector/ResponseHandler/Update.php new file mode 100644 index 0000000000000..73fc575ae2821 --- /dev/null +++ b/app/code/Magento/Analytics/Model/Connector/ResponseHandler/Update.php @@ -0,0 +1,24 @@ +analyticsToken = $analyticsToken; $this->integrationManager = $integrationManager; - $this->signUpRequest = $signUpRequest; + $this->config = $config; + $this->httpClient = $httpClient; + $this->logger = $logger; + $this->responseResolver = $responseResolver; } /** @@ -61,14 +95,32 @@ public function __construct( */ public function execute() { + $result = false; $integrationToken = $this->integrationManager->generateToken(); if ($integrationToken) { $this->integrationManager->activateIntegration(); - $responseToken = $this->signUpRequest->call($integrationToken->getToken()); - if ($responseToken) { - $this->analyticsToken->storeToken($responseToken); + $response = $this->httpClient->request( + ZendClient::POST, + $this->config->getConfigDataValue($this->signUpUrlPath), + [ + "token" => $integrationToken->getData('token'), + "url" => $this->config->getConfigDataValue( + Store::XML_PATH_SECURE_BASE_URL + ) + ] + ); + + $result = $this->responseResolver->getResult($response); + if (!$result) { + $this->logger->warning( + sprintf( + 'Subscription for MBI service has been failed. An error occurred during token exchange: %s', + !empty($response->getBody()) ? $response->getBody() : 'Response body is empty.' + ) + ); } } - return ((bool)$integrationToken && isset($responseToken) && (bool)$responseToken); + + return $result; } } diff --git a/app/code/Magento/Analytics/Model/Connector/SignUpRequest.php b/app/code/Magento/Analytics/Model/Connector/SignUpRequest.php deleted file mode 100644 index 98062b230868d..0000000000000 --- a/app/code/Magento/Analytics/Model/Connector/SignUpRequest.php +++ /dev/null @@ -1,135 +0,0 @@ -config = $config; - $this->httpClient = $httpClient; - $this->logger = $logger; - } - - /** - * Prepares request data in JSON format. - * - * @param string $integrationToken - * @return string - */ - private function getRequestJson($integrationToken) - { - return json_encode( - [ - "token" => $integrationToken, - "url" => $this->config->getConfigDataValue( - Store::XML_PATH_SECURE_BASE_URL - ) - ] - ); - } - - /** - * Extracts an MBI access token from the response. - * - * Returns the token or FALSE if the token is not found. - * - * @param HttpResponse $response - * @return string|false - */ - private function extractAccessToken(HttpResponse $response) - { - $token = false; - - if ($response->getStatus() === 201) { - $body = json_decode($response->getBody(), 1); - - if (isset($body['access-token']) && !empty($body['access-token'])) { - $token = $body['access-token']; - } - } - - return $token; - } - - /** - * Performs a 'signUp' call to MBI service. - * - * Returns MBI access token or FALSE in case of failure. - * - * @param string $integrationToken - * @return string|false - */ - public function call($integrationToken) - { - $token = false; - - try { - $response = $this->httpClient->request( - ZendClient::POST, - $this->config->getConfigDataValue($this->signUpUrlPath), - $this->getRequestJson($integrationToken), - ['Content-Type: application/json'] - ); - - if ($response) { - $token = $this->extractAccessToken($response); - - if (!$token) { - $this->logger->warning( - sprintf( - 'Subscription for MBI service has been failed. An error occurred during token exchange: %s', - !empty($response->getBody()) ? $response->getBody() : 'Response body is empty.' - ) - ); - } - } - } catch (\Exception $e) { - $this->logger->critical($e); - } - - return $token; - } -} diff --git a/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php b/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php index 185b2c1ebe606..a2d64a98e0409 100644 --- a/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php +++ b/app/code/Magento/Analytics/Model/Connector/UpdateCommand.php @@ -6,6 +6,7 @@ namespace Magento\Analytics\Model\Connector; use Magento\Analytics\Model\AnalyticsToken; +use Magento\Analytics\Model\Connector\Http\ResponseResolver; use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin; use Magento\Config\Model\Config; use Magento\Framework\FlagManager; @@ -49,76 +50,66 @@ class UpdateCommand implements CommandInterface */ private $flagManager; + /** + * @var ResponseResolver + */ + private $responseResolver; + /** * @param AnalyticsToken $analyticsToken * @param Http\ClientInterface $httpClient * @param Config $config * @param LoggerInterface $logger * @param FlagManager $flagManager + * @param ResponseResolver $responseResolver */ public function __construct( AnalyticsToken $analyticsToken, Http\ClientInterface $httpClient, Config $config, LoggerInterface $logger, - FlagManager $flagManager + FlagManager $flagManager, + ResponseResolver $responseResolver ) { $this->analyticsToken = $analyticsToken; $this->httpClient = $httpClient; $this->config = $config; $this->logger = $logger; $this->flagManager = $flagManager; + $this->responseResolver = $responseResolver; } /** * Executes update request to MBI api in case store url was changed + * * @return bool */ public function execute() { $result = false; - try { - if ($this->analyticsToken->isTokenExist()) { - $response = $this->httpClient->request( - ZendClient::PUT, - $this->config->getConfigDataValue($this->updateUrlPath), - $this->getRequestJson(), - ['Content-Type: application/json'] + if ($this->analyticsToken->isTokenExist()) { + $response = $this->httpClient->request( + ZendClient::PUT, + $this->config->getConfigDataValue($this->updateUrlPath), + [ + "url" => $this->flagManager->getFlagData(BaseUrlConfigPlugin::OLD_BASE_URL_FLAG_CODE), + "new-url" => $this->config->getConfigDataValue( + Store::XML_PATH_SECURE_BASE_URL + ), + "access-token" => $this->analyticsToken->getToken(), + ] + ); + $result = $this->responseResolver->getResult($response); + if (!$result) { + $this->logger->warning( + sprintf( + 'Update of the subscription for MBI service has been failed: %s', + !empty($response->getBody()) ? $response->getBody() : 'Response body is empty.' + ) ); - - if ($response) { - $result = $response->getStatus() === 201; - if (!$result) { - $this->logger->warning( - sprintf( - 'Update of the subscription for MBI service has been failed: %s', - !empty($response->getBody()) ? $response->getBody() : 'Response body is empty.' - ) - ); - } - } } - } catch (\Exception $e) { - $this->logger->critical($e); } return $result; } - - /** - * Prepares request data in JSON format. - * @return string - */ - private function getRequestJson() - { - return json_encode( - [ - "url" => $this->flagManager->getFlagData(BaseUrlConfigPlugin::OLD_BASE_URL_FLAG_CODE), - "new-url" => $this->config->getConfigDataValue( - Store::XML_PATH_SECURE_BASE_URL - ), - "access-token" => $this->analyticsToken->getToken(), - ] - ); - } } diff --git a/app/code/Magento/Analytics/Model/IntegrationManager.php b/app/code/Magento/Analytics/Model/IntegrationManager.php index 342fecb70f847..61a40a955e026 100644 --- a/app/code/Magento/Analytics/Model/IntegrationManager.php +++ b/app/code/Magento/Analytics/Model/IntegrationManager.php @@ -76,7 +76,7 @@ public function activateIntegration() /** * This method execute Generate Token command and enable integration * - * @return bool|string + * @return bool|\Magento\Integration\Model\Oauth\Token */ public function generateToken() { diff --git a/app/code/Magento/Analytics/Model/LinkProvider.php b/app/code/Magento/Analytics/Model/LinkProvider.php index 58fcadf1be252..2474653f4916c 100644 --- a/app/code/Magento/Analytics/Model/LinkProvider.php +++ b/app/code/Magento/Analytics/Model/LinkProvider.php @@ -7,6 +7,7 @@ use Magento\Analytics\Api\Data\LinkInterfaceFactory; use Magento\Analytics\Api\LinkProviderInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\UrlInterface; use Magento\Store\Model\StoreManagerInterface; @@ -74,7 +75,7 @@ public function get() { $fileInfo = $this->fileInfoManager->load(); if (!$this->isFileReady($fileInfo)) { - throw new \Magento\Framework\Exception\NotFoundException(__('File is not ready yet.')); + throw new NoSuchEntityException(__('File is not ready yet.')); } return $this->linkFactory->create( [ diff --git a/app/code/Magento/Analytics/Model/NotificationTime.php b/app/code/Magento/Analytics/Model/NotificationTime.php index 47b9f35cc77b9..9272542f4dedd 100644 --- a/app/code/Magento/Analytics/Model/NotificationTime.php +++ b/app/code/Magento/Analytics/Model/NotificationTime.php @@ -25,7 +25,7 @@ class NotificationTime /** * NotificationTime constructor. * - * @param \Magento\Analytics\Model\FlagManager $flagManager + * @param FlagManager $flagManager */ public function __construct( FlagManager $flagManager diff --git a/app/code/Magento/Analytics/Model/Subscription.php b/app/code/Magento/Analytics/Model/Subscription.php deleted file mode 100644 index ddbab2dce93b2..0000000000000 --- a/app/code/Magento/Analytics/Model/Subscription.php +++ /dev/null @@ -1,144 +0,0 @@ -configValueFactory = $configValueFactory; - $this->configStructure = $configStructure; - $this->configValueResource = $configValueResource; - $this->reinitableConfig = $reinitableConfig; - $this->subscriptionHandler = $subscriptionHandler; - $this->statusProvider = $statusProvider; - } - - /** - * Set subscription enabled config value. - * - * @return boolean - */ - public function enable() - { - /** @var Field $field */ - $field = $this->configStructure->getElement($this->enabledConfigStructurePath); - /** @var Value $configValue */ - $configValue = $field->hasBackendModel() - ? $field->getBackendModel() - : $this->configValueFactory->create(); - $configPath = $field->getConfigPath() ?: $this->enabledConfigStructurePath; - - $this->configValueResource - ->load($configValue, $configPath, 'path'); - - $configValue->setValue($this->yesValueDropdown); - $configValue->setPath($configPath); - - $this->configValueResource - ->save($configValue); - - $this->reinitableConfig->reinit(); - - return true; - } - - /** - * Retry process of subscription that was unsuccessful. - * - * @return bool - */ - public function retry() - { - if ($this->statusProvider->getStatus() === SubscriptionStatusProvider::FAILED) { - $this->subscriptionHandler->processEnabled(); - $this->reinitableConfig->reinit(); - } - - return true; - } -} diff --git a/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php b/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php index fc363231cf4d5..8fe548013c206 100644 --- a/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php +++ b/app/code/Magento/Analytics/Model/SubscriptionStatusProvider.php @@ -6,7 +6,7 @@ namespace Magento\Analytics\Model; use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler; -use Magento\Config\App\Config\Type\System; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\FlagManager; /** @@ -35,9 +35,9 @@ class SubscriptionStatusProvider const DISABLED = "Disabled"; /** - * @var System + * @var ScopeConfigInterface */ - private $systemConfig; + private $scopeConfig; /** * @var AnalyticsToken @@ -50,16 +50,16 @@ class SubscriptionStatusProvider private $flagManager; /** - * @param System $systemConfig + * @param ScopeConfigInterface $scopeConfig * @param AnalyticsToken $analyticsToken * @param FlagManager $flagManager */ public function __construct( - System $systemConfig, + ScopeConfigInterface $scopeConfig, AnalyticsToken $analyticsToken, FlagManager $flagManager ) { - $this->systemConfig = $systemConfig; + $this->scopeConfig = $scopeConfig; $this->analyticsToken = $analyticsToken; $this->flagManager = $flagManager; } @@ -77,7 +77,7 @@ public function __construct( */ public function getStatus() { - $isSubscriptionEnabledInConfig = $this->systemConfig->get('default/analytics/subscription/enabled'); + $isSubscriptionEnabledInConfig = $this->scopeConfig->getValue('analytics/subscription/enabled'); if ($isSubscriptionEnabledInConfig) { return $this->getStatusForEnabledSubscription(); } diff --git a/app/code/Magento/Analytics/ReportXml/DB/Assembler/FromAssembler.php b/app/code/Magento/Analytics/ReportXml/DB/Assembler/FromAssembler.php index 1d890a6349128..811119ace221b 100644 --- a/app/code/Magento/Analytics/ReportXml/DB/Assembler/FromAssembler.php +++ b/app/code/Magento/Analytics/ReportXml/DB/Assembler/FromAssembler.php @@ -9,10 +9,9 @@ use Magento\Analytics\ReportXml\DB\ColumnsResolver; use Magento\Analytics\ReportXml\DB\SelectBuilder; use Magento\Analytics\ReportXml\DB\NameResolver; +use Magento\Framework\App\ResourceConnection; /** - * Class FromAssembler - * * Assembles FROM condition */ class FromAssembler implements AssemblerInterface @@ -28,17 +27,23 @@ class FromAssembler implements AssemblerInterface private $columnsResolver; /** - * FromAssembler constructor. - * + * @var ResourceConnection + */ + private $resourceConnection; + + /** * @param NameResolver $nameResolver * @param ColumnsResolver $columnsResolver + * @param ResourceConnection $resourceConnection */ public function __construct( NameResolver $nameResolver, - ColumnsResolver $columnsResolver + ColumnsResolver $columnsResolver, + ResourceConnection $resourceConnection ) { $this->nameResolver = $nameResolver; $this->columnsResolver = $columnsResolver; + $this->resourceConnection = $resourceConnection; } /** @@ -52,8 +57,9 @@ public function assemble(SelectBuilder $selectBuilder, $queryConfig) { $selectBuilder->setFrom( [ - $this->nameResolver->getAlias($queryConfig['source']) - => $this->nameResolver->getName($queryConfig['source']) + $this->nameResolver->getAlias($queryConfig['source']) => + $this->resourceConnection + ->getTableName($this->nameResolver->getName($queryConfig['source'])), ] ); $columns = $this->columnsResolver->getColumns($selectBuilder, $queryConfig['source']); diff --git a/app/code/Magento/Analytics/ReportXml/DB/Assembler/JoinAssembler.php b/app/code/Magento/Analytics/ReportXml/DB/Assembler/JoinAssembler.php index 608c1d7b1159f..f3c6540a25171 100644 --- a/app/code/Magento/Analytics/ReportXml/DB/Assembler/JoinAssembler.php +++ b/app/code/Magento/Analytics/ReportXml/DB/Assembler/JoinAssembler.php @@ -10,6 +10,7 @@ use Magento\Analytics\ReportXml\DB\SelectBuilder; use Magento\Analytics\ReportXml\DB\ConditionResolver; use Magento\Analytics\ReportXml\DB\ColumnsResolver; +use Magento\Framework\App\ResourceConnection; /** * Class JoinAssembler @@ -34,20 +35,26 @@ class JoinAssembler implements AssemblerInterface private $columnsResolver; /** - * JoinAssembler constructor. - * + * @var ResourceConnection + */ + private $resourceConnection; + + /** * @param ConditionResolver $conditionResolver * @param ColumnsResolver $columnsResolver * @param NameResolver $nameResolver + * @param ResourceConnection $resourceConnection */ public function __construct( ConditionResolver $conditionResolver, ColumnsResolver $columnsResolver, - NameResolver $nameResolver + NameResolver $nameResolver, + ResourceConnection $resourceConnection ) { $this->conditionResolver = $conditionResolver; $this->nameResolver = $nameResolver; $this->columnsResolver = $columnsResolver; + $this->resourceConnection = $resourceConnection; } /** @@ -73,7 +80,8 @@ public function assemble(SelectBuilder $selectBuilder, $queryConfig) $joins[$joinAlias] = [ 'link-type' => isset($join['link-type']) ? $join['link-type'] : 'left', 'table' => [ - $joinAlias => $this->nameResolver->getName($join) + $joinAlias => $this->resourceConnection + ->getTableName($this->nameResolver->getName($join)), ], 'condition' => $this->conditionResolver->getFilter( $selectBuilder, diff --git a/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/ActivateTest.php b/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/ActivateTest.php index 3e649b6ab223c..9097349e9137c 100644 --- a/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/ActivateTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/ActivateTest.php @@ -8,11 +8,12 @@ use Magento\Analytics\Controller\Adminhtml\Subscription\Activate; use Magento\Analytics\Model\NotificationTime; -use Magento\Analytics\Model\Subscription; +use Magento\Config\Model\PreparedValueFactory; use Magento\Framework\App\RequestInterface; use Magento\Framework\Controller\Result\Json; use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Model\ResourceModel\Db\AbstractDb; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Psr\Log\LoggerInterface; @@ -32,9 +33,14 @@ class ActivateTest extends \PHPUnit_Framework_TestCase private $resultJsonMock; /** - * @var Subscription|\PHPUnit_Framework_MockObject_MockObject + * @var PreparedValueFactory|\PHPUnit_Framework_MockObject_MockObject */ - private $subscriptionModelMock; + private $preparedValueFactoryMock; + + /** + * @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject + */ + private $configValueResourceMock; /** * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject @@ -79,7 +85,11 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->subscriptionModelMock = $this->getMockBuilder(Subscription::class) + $this->preparedValueFactoryMock = $this->getMockBuilder(PreparedValueFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->configValueResourceMock = $this->getMockBuilder(AbstractDb::class) ->disableOriginalConstructor() ->getMock(); @@ -101,7 +111,8 @@ protected function setUp() Activate::class, [ 'resultFactory' => $this->resultFactoryMock, - 'subscription' => $this->subscriptionModelMock, + 'preparedValueFactory' => $this->preparedValueFactoryMock, + 'configValueResource' => $this->configValueResourceMock, 'logger' => $this->loggerMock, 'notificationTime' => $this->notificationTimeMock, '_request' => $this->requestMock, @@ -130,10 +141,12 @@ public function testExecute($isSubscriptionEnabled) ->willReturn($isSubscriptionEnabled); if ($isSubscriptionEnabled) { - $this->subscriptionModelMock + $configValue = $this->createConfigValueMock(); + $this->preparedValueFactoryMock ->expects($this->once()) - ->method('enable') - ->willReturn(true); + ->method('create') + ->willReturn($configValue); + $this->configValueResourceMock->expects($this->once())->method('save')->with($configValue); } else { $this->notificationTimeMock ->expects($this->once()) @@ -168,9 +181,9 @@ public function testExecuteWithException(\Exception $exception) ->with($this->subscriptionApprovedField) ->willReturn(true); - $this->subscriptionModelMock + $this->preparedValueFactoryMock ->expects($this->once()) - ->method('enable') + ->method('create') ->willThrowException($exception); $this->loggerMock ->expects($this->once()) @@ -205,6 +218,16 @@ public function testExecuteWithException(\Exception $exception) ); } + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function createConfigValueMock() + { + return $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class) + ->disableOriginalConstructor() + ->getMock(); + } + /** * @return array */ diff --git a/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/RetryTest.php b/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/RetryTest.php index 3562a544cc4cc..2c921e2260140 100644 --- a/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/RetryTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Controller/Adminhtml/Subscription/RetryTest.php @@ -7,7 +7,7 @@ namespace Magento\Analytics\Test\Unit\Controller\Adminhtml\Subscription; use Magento\Analytics\Controller\Adminhtml\Subscription\Retry; -use Magento\Analytics\Model\Subscription; +use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler; use Magento\Framework\Controller\Result\Redirect; use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\LocalizedException; @@ -31,9 +31,9 @@ class RetryTest extends \PHPUnit_Framework_TestCase private $resultRedirectMock; /** - * @var Subscription|\PHPUnit_Framework_MockObject_MockObject + * @var SubscriptionHandler|\PHPUnit_Framework_MockObject_MockObject */ - private $subscriptionMock; + private $subscriptionHandlerMock; /** * @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject @@ -63,7 +63,7 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->subscriptionMock = $this->getMockBuilder(Subscription::class) + $this->subscriptionHandlerMock = $this->getMockBuilder(SubscriptionHandler::class) ->disableOriginalConstructor() ->getMock(); @@ -77,7 +77,7 @@ protected function setUp() Retry::class, [ 'resultFactory' => $this->resultFactoryMock, - 'subscription' => $this->subscriptionMock, + 'subscriptionHandler' => $this->subscriptionHandlerMock, 'messageManager' => $this->messageManagerMock, ] ); @@ -98,9 +98,9 @@ public function testExecute() ->method('setPath') ->with('adminhtml') ->willReturnSelf(); - $this->subscriptionMock + $this->subscriptionHandlerMock ->expects($this->once()) - ->method('retry') + ->method('processEnabled') ->with() ->willReturn(true); $this->assertSame( @@ -127,9 +127,9 @@ public function testExecuteWithException(\Exception $exception, Phrase $message) ->method('setPath') ->with('adminhtml') ->willReturnSelf(); - $this->subscriptionMock + $this->subscriptionHandlerMock ->expects($this->once()) - ->method('retry') + ->method('processEnabled') ->with() ->willThrowException($exception); $this->messageManagerMock diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/Client/CurlTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/Client/CurlTest.php index 1d23cc8d9f631..6890fe200f9dc 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/Client/CurlTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/Client/CurlTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Analytics\Test\Unit\Model\Connector\Http\Client; +use Magento\Analytics\Model\Connector\Http\ConverterInterface; +use Magento\Analytics\Model\Connector\Http\JsonConverter; use Magento\Framework\HTTP\Adapter\CurlFactory; /** @@ -27,11 +29,6 @@ class CurlTest extends \PHPUnit_Framework_TestCase */ private $loggerMock; - /** - * @var \Zend_Http_Response|\PHPUnit_Framework_MockObject_MockObject - */ - private $responseMock; - /** * @var CurlFactory|\PHPUnit_Framework_MockObject_MockObject */ @@ -42,6 +39,11 @@ class CurlTest extends \PHPUnit_Framework_TestCase */ private $responseFactoryMock; + /** + * @var ConverterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $converterMock; + /** * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ @@ -63,13 +65,6 @@ protected function setUp() ) ->disableOriginalConstructor() ->getMock(); - - $this->responseMock = $this->getMockBuilder( - \Zend_Http_Response::class - ) - ->disableOriginalConstructor() - ->getMock(); - $this->curlFactoryMock = $this->getMockBuilder(CurlFactory::class) ->setMethods(['create']) ->disableOriginalConstructor() @@ -83,6 +78,7 @@ protected function setUp() ) ->disableOriginalConstructor() ->getMock(); + $this->converterMock = $this->createJsonConverter(); $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -92,7 +88,8 @@ protected function setUp() [ 'curlFactory' => $this->curlFactoryMock, 'responseFactory' => $this->responseFactoryMock, - 'logger' => $this->loggerMock + 'converter' => $this->converterMock, + 'logger' => $this->loggerMock, ] ); } @@ -108,9 +105,9 @@ public function getTestData() [ 'data' => [ 'version' => '1.1', - 'body'=> '{"name": "value"}', + 'body'=> ['name' => 'value'], 'url' => 'http://www.mystore.com', - 'headers' => ['Content-Type: application/json'], + 'headers' => [JsonConverter::CONTENT_TYPE_HEADER], 'method' => \Magento\Framework\HTTP\ZendClient::POST, ] ] @@ -124,7 +121,7 @@ public function getTestData() public function testRequestSuccess(array $data) { $responseString = 'This is response.'; - + $response = new \Zend_Http_Response(201, [], $responseString); $this->curlMock->expects($this->once()) ->method('write') ->with( @@ -132,7 +129,7 @@ public function testRequestSuccess(array $data) $data['url'], $data['version'], $data['headers'], - $data['version'] + json_encode($data['body']) ); $this->curlMock->expects($this->once()) ->method('read') @@ -144,14 +141,14 @@ public function testRequestSuccess(array $data) $this->responseFactoryMock->expects($this->any()) ->method('create') ->with($responseString) - ->willReturn($this->responseMock); + ->willReturn($response); $this->assertEquals( - $this->responseMock, + $response, $this->subject->request( $data['method'], $data['url'], - $data['version'], + $data['body'], $data['headers'], $data['version'] ) @@ -164,6 +161,7 @@ public function testRequestSuccess(array $data) */ public function testRequestError(array $data) { + $response = new \Zend_Http_Response(0, []); $this->curlMock->expects($this->once()) ->method('write') ->with( @@ -171,7 +169,7 @@ public function testRequestError(array $data) $data['url'], $data['version'], $data['headers'], - $data['version'] + json_encode($data['body']) ); $this->curlMock->expects($this->once()) ->method('read'); @@ -190,14 +188,31 @@ public function testRequestError(array $data) ) ); - $this->assertFalse( + $this->assertEquals( + $response, $this->subject->request( $data['method'], $data['url'], - $data['version'], + $data['body'], $data['headers'], $data['version'] ) ); } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function createJsonConverter() + { + $converterMock = $this->getMockBuilder(ConverterInterface::class) + ->getMockForAbstractClass(); + $converterMock->expects($this->any())->method('toBody')->willReturnCallback(function ($value) { + return json_encode($value); + }); + $converterMock->expects($this->any()) + ->method('getContentTypeHeader') + ->willReturn(JsonConverter::CONTENT_TYPE_HEADER); + return $converterMock; + } } diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/JsonConverterTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/JsonConverterTest.php new file mode 100644 index 0000000000000..7ac6f50ea24c4 --- /dev/null +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/JsonConverterTest.php @@ -0,0 +1,34 @@ +assertEquals(JsonConverter::CONTENT_TYPE_HEADER, $converter->getContentTypeHeader()); + } + + public function testConvertBody() + { + $body = '{"token": "secret-token"}'; + $converter = new JsonConverter(); + $this->assertEquals(json_decode($body, 1), $converter->fromBody($body)); + } + + public function testConvertData() + { + $data = ["token" => "secret-token"]; + $converter = new JsonConverter(); + $this->assertEquals(json_encode($data), $converter->toBody($data)); + } +} diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/ResponseResolverTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/ResponseResolverTest.php new file mode 100644 index 0000000000000..5047e8a9dd391 --- /dev/null +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/Http/ResponseResolverTest.php @@ -0,0 +1,39 @@ + 'testValue']; + $response = new \Zend_Http_Response(201, [], json_encode($expectedBody)); + $responseHandlerMock = $this->getMockBuilder(ResponseHandlerInterface::class) + ->getMockForAbstractClass(); + $responseHandlerMock->expects($this->once()) + ->method('handleResponse') + ->with($expectedBody) + ->willReturn(true); + $notFoundResponseHandlerMock = $this->getMockBuilder(ResponseHandlerInterface::class) + ->getMockForAbstractClass(); + $notFoundResponseHandlerMock->expects($this->never())->method('handleResponse'); + $responseResolver = new ResponseResolver( + new JsonConverter(), + [ + 201 => $responseHandlerMock, + 404 => $notFoundResponseHandlerMock, + ] + ); + $this->assertTrue($responseResolver->getResult($response)); + } +} diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/NotifyDataChangedCommandTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/NotifyDataChangedCommandTest.php index ea43fcd836521..a30211c7f3475 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/Connector/NotifyDataChangedCommandTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/NotifyDataChangedCommandTest.php @@ -6,11 +6,13 @@ namespace Magento\Analytics\Test\Unit\Model\Connector; use Magento\Analytics\Model\AnalyticsToken; -use Magento\Analytics\Model\Connector\Http\ClientInterface; -use Magento\Analytics\Model\Connector\NotifyDataChangedCommand; -use Magento\Config\Model\Config; +use Magento\Analytics\Model\Connector\Http\JsonConverter; +use Magento\Analytics\Model\Connector\Http\ResponseResolver; use Magento\Framework\HTTP\ZendClient; +use Magento\Config\Model\Config; use Psr\Log\LoggerInterface; +use Magento\Analytics\Model\Connector\NotifyDataChangedCommand; +use Magento\Analytics\Model\Connector\Http\ClientInterface; class NotifyDataChangedCommandTest extends \PHPUnit_Framework_TestCase { @@ -39,11 +41,6 @@ class NotifyDataChangedCommandTest extends \PHPUnit_Framework_TestCase */ private $loggerMock; - /** - * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $responseMock; - protected function setUp() { $this->analyticsTokenMock = $this->getMockBuilder(AnalyticsToken::class) @@ -61,15 +58,16 @@ protected function setUp() $this->loggerMock = $this->getMockBuilder(LoggerInterface::class) ->disableOriginalConstructor() ->getMock(); - - $this->responseMock = $this->getMockBuilder(\Zend_Http_Response::class) - ->disableOriginalConstructor() - ->getMock(); + $successHandler = $this->getMockBuilder(\Magento\Analytics\Model\Connector\Http\ResponseHandlerInterface::class) + ->getMockForAbstractClass(); + $successHandler->method('handleResponse') + ->willReturn(true); $this->notifyDataChangedCommand = new NotifyDataChangedCommand( $this->analyticsTokenMock, $this->httpClientMock, $this->configMock, + new ResponseResolver(new JsonConverter(), [201 => $successHandler]), $this->loggerMock ); } @@ -78,7 +76,6 @@ public function testExecuteSuccess() { $configVal = "Config val"; $token = "Secret token!"; - $requestJson = sprintf('{"access-token":"%s","url":"%s"}', $token, $configVal); $this->analyticsTokenMock->expects($this->once()) ->method('isTokenExist') ->willReturn(true); @@ -93,9 +90,8 @@ public function testExecuteSuccess() ->with( ZendClient::POST, $configVal, - $requestJson, - ['Content-Type: application/json'] - )->willReturn($this->responseMock); + ['access-token' => $token, 'url' => $configVal] + )->willReturn(new \Zend_Http_Response(201, [])); $this->assertTrue($this->notifyDataChangedCommand->execute()); } @@ -104,6 +100,8 @@ public function testExecuteWithoutToken() $this->analyticsTokenMock->expects($this->once()) ->method('isTokenExist') ->willReturn(false); + $this->httpClientMock->expects($this->never()) + ->method('request'); $this->assertFalse($this->notifyDataChangedCommand->execute()); } } diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/OTPRequestTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/OTPRequestTest.php index d27217c90fa2d..a33d7d0d7c1bf 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/Connector/OTPRequestTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/OTPRequestTest.php @@ -5,92 +5,79 @@ */ namespace Magento\Analytics\Test\Unit\Model\Connector; +use Magento\Analytics\Model\AnalyticsToken; +use Magento\Analytics\Model\Connector\Http\ClientInterface; +use Magento\Analytics\Model\Connector\Http\ResponseResolver; +use Magento\Analytics\Model\Connector\OTPRequest; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Psr\Log\LoggerInterface; + /** * A unit test for testing of the representation of a 'OTP' request. */ class OTPRequestTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Analytics\Model\Connector\OTPRequest + * @var OTPRequest */ private $subject; /** - * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */ private $loggerMock; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ private $configMock; /** - * @var \Zend_Http_Response|\PHPUnit_Framework_MockObject_MockObject - */ - private $responseMock; - - /** - * @var \Magento\Analytics\Model\Connector\Http\ClientInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject */ private $httpClientMock; /** - * @var \Magento\Analytics\Model\AnalyticsToken|\PHPUnit_Framework_MockObject_MockObject + * @var AnalyticsToken|\PHPUnit_Framework_MockObject_MockObject */ private $analyticsTokenMock; /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var ResponseResolver|\PHPUnit_Framework_MockObject_MockObject */ - private $objectManagerHelper; + private $responseResolverMock; /** * @return void */ public function setUp() { - $this->loggerMock = $this->getMockBuilder( - \Psr\Log\LoggerInterface::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->configMock = $this->getMockBuilder( - \Magento\Framework\App\Config\ScopeConfigInterface::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->responseMock = $this->getMockBuilder( - \Zend_Http_Response::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->httpClientMock = $this->getMockBuilder( - \Magento\Analytics\Model\Connector\Http\ClientInterface::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->analyticsTokenMock = $this->getMockBuilder( - \Magento\Analytics\Model\AnalyticsToken::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->objectManagerHelper = - new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->subject = $this->objectManagerHelper->getObject( - \Magento\Analytics\Model\Connector\OTPRequest::class, - [ - 'analyticsToken' => $this->analyticsTokenMock, - 'config' => $this->configMock, - 'httpClient' => $this->httpClientMock, - 'logger' => $this->loggerMock - ] + $this->loggerMock = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->configMock = $this->getMockBuilder(ScopeConfigInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->httpClientMock = $this->getMockBuilder(ClientInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->analyticsTokenMock = $this->getMockBuilder(AnalyticsToken::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->responseResolverMock = $this->getMockBuilder(ResponseResolver::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->subject = new OTPRequest( + $this->analyticsTokenMock, + $this->httpClientMock, + $this->configMock, + $this->responseResolverMock, + $this->loggerMock ); } @@ -105,9 +92,8 @@ private function getTestData() 'otp' => 'thisisotp', 'url' => 'http://www.mystore.com', 'access-token' => 'thisisaccesstoken', - 'headers' => ['Content-Type: application/json'], 'method' => \Magento\Framework\HTTP\ZendClient::POST, - 'body'=> '{"access-token":"thisisaccesstoken","url":"http:\/\/www.mystore.com"}', + 'body'=> ['access-token' => 'thisisaccesstoken','url' => 'http://www.mystore.com'], ]; } @@ -134,17 +120,12 @@ public function testCallSuccess() ->with( $data['method'], $data['url'], - $data['body'], - $data['headers'] + $data['body'] ) - ->willReturn($this->responseMock); - - $this->responseMock->expects($this->any()) - ->method('getStatus') - ->willReturn(201); - $this->responseMock->expects($this->any()) - ->method('getBody') - ->willReturn('{"otp": "' . $data['otp'] . '"}'); + ->willReturn(new \Zend_Http_Response(201, [])); + $this->responseResolverMock->expects($this->once()) + ->method('getResult') + ->willReturn($data['otp']); $this->assertEquals( $data['otp'], @@ -167,37 +148,6 @@ public function testCallNoAccessToken() $this->assertFalse($this->subject->call()); } - /** - * @return void - */ - public function testCallTransportFailure() - { - $data = $this->getTestData(); - - $this->analyticsTokenMock->expects($this->once()) - ->method('isTokenExist') - ->willReturn(true); - $this->analyticsTokenMock->expects($this->once()) - ->method('getToken') - ->willReturn($data['access-token']); - - $this->configMock->expects($this->any()) - ->method('getValue') - ->willReturn($data['url']); - - $this->httpClientMock->expects($this->once()) - ->method('request') - ->with( - $data['method'], - $data['url'], - $data['body'], - $data['headers'] - ) - ->willReturn(false); - - $this->assertFalse($this->subject->call()); - } - /** * @return void */ @@ -221,55 +171,17 @@ public function testCallNoOtp() ->with( $data['method'], $data['url'], - $data['body'], - $data['headers'] + $data['body'] ) - ->willReturn($this->responseMock); + ->willReturn(new \Zend_Http_Response(0, [])); - $this->responseMock->expects($this->any()) - ->method('getStatus') - ->willReturn(409); + $this->responseResolverMock->expects($this->once()) + ->method('getResult') + ->willReturn(false); $this->loggerMock->expects($this->once()) ->method('warning'); $this->assertFalse($this->subject->call()); } - - /** - * @return void - */ - public function testCallException() - { - $data = $this->getTestData(); - - $exception = new \Exception('Test Exception'); - - $this->analyticsTokenMock->expects($this->once()) - ->method('isTokenExist') - ->willReturn(true); - $this->analyticsTokenMock->expects($this->once()) - ->method('getToken') - ->willReturn($data['access-token']); - - $this->configMock->expects($this->any()) - ->method('getValue') - ->willReturn($data['url']); - - $this->httpClientMock->expects($this->once()) - ->method('request') - ->with( - $data['method'], - $data['url'], - $data['body'], - $data['headers'] - ) - ->willThrowException($exception); - - $this->loggerMock->expects($this->once()) - ->method('critical') - ->with($exception); - - $this->assertFalse($this->subject->call()); - } } diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/OTPTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/OTPTest.php new file mode 100644 index 0000000000000..203eb57157e0e --- /dev/null +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/OTPTest.php @@ -0,0 +1,22 @@ +assertFalse($OTPHandler->handleResponse([])); + $expectedOtp = 123; + $this->assertEquals($expectedOtp, $OTPHandler->handleResponse(['otp' => $expectedOtp])); + } +} diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/ReSignUpTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/ReSignUpTest.php new file mode 100644 index 0000000000000..4c3dde7a92c3f --- /dev/null +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/ReSignUpTest.php @@ -0,0 +1,36 @@ +getMockBuilder(AnalyticsToken::class) + ->disableOriginalConstructor() + ->getMock(); + $analyticsToken->expects($this->once()) + ->method('storeToken') + ->with(null); + $subscriptionHandler = $this->getMockBuilder(SubscriptionHandler::class) + ->disableOriginalConstructor() + ->getMock(); + $subscriptionStatusProvider = $this->getMockBuilder(SubscriptionStatusProvider::class) + ->disableOriginalConstructor() + ->getMock(); + $subscriptionStatusProvider->method('getStatus')->willReturn(SubscriptionStatusProvider::ENABLED); + $reSignUpHandler = new ReSignUp($analyticsToken, $subscriptionHandler, $subscriptionStatusProvider); + $this->assertFalse($reSignUpHandler->handleResponse([])); + } +} diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/SignUpTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/SignUpTest.php new file mode 100644 index 0000000000000..2bbd528638a19 --- /dev/null +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/SignUpTest.php @@ -0,0 +1,30 @@ +getMockBuilder(AnalyticsToken::class) + ->disableOriginalConstructor() + ->getMock(); + $analyticsToken->expects($this->once()) + ->method('storeToken') + ->with($accessToken); + $signUpHandler = new SignUp($analyticsToken, new JsonConverter()); + $this->assertFalse($signUpHandler->handleResponse([])); + $this->assertEquals($accessToken, $signUpHandler->handleResponse(['access-token' => $accessToken])); + } +} diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/UpdateTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/UpdateTest.php new file mode 100644 index 0000000000000..90102e2c3d868 --- /dev/null +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/ResponseHandler/UpdateTest.php @@ -0,0 +1,20 @@ +assertTrue($updateHandler->handleResponse([])); + } +} diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/SignUpCommandTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/SignUpCommandTest.php index 6d35e7562e8c7..624728f3440c9 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/Connector/SignUpCommandTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/SignUpCommandTest.php @@ -5,12 +5,15 @@ */ namespace Magento\Analytics\Test\Unit\Model\Connector; +use Magento\Analytics\Model\Connector\Http\ClientInterface; +use Magento\Analytics\Model\Connector\Http\JsonConverter; +use Magento\Analytics\Model\Connector\Http\ResponseResolver; use Magento\Analytics\Model\Connector\SignUpCommand; -use Magento\Analytics\Model\Connector\SignUpRequest; use Magento\Analytics\Model\AnalyticsToken; use Magento\Analytics\Model\IntegrationManager; +use Magento\Config\Model\Config; use Magento\Integration\Model\Oauth\Token as IntegrationToken; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Psr\Log\LoggerInterface; /** * Class SignUpCommandTest @@ -38,9 +41,24 @@ class SignUpCommandTest extends \PHPUnit_Framework_TestCase private $integrationToken; /** - * @var SignUpRequest|\PHPUnit_Framework_MockObject_MockObject + * @var Config|\PHPUnit_Framework_MockObject_MockObject */ - private $signUpRequestMock; + private $configMock; + + /** + * @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $httpClientMock; + + /** + * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $loggerMock; + + /** + * @var ResponseResolver|\PHPUnit_Framework_MockObject_MockObject + */ + private $responseResolverMock; protected function setUp() { @@ -52,22 +70,27 @@ protected function setUp() ->getMock(); $this->integrationToken = $this->getMockBuilder(IntegrationToken::class) ->disableOriginalConstructor() - ->setMethods(['getToken']) ->getMock(); - $this->integrationToken->expects($this->any()) - ->method('getToken') - ->willReturn('IntegrationToken'); - $this->signUpRequestMock = $this->getMockBuilder(SignUpRequest::class) + $this->configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + $this->httpClientMock = $this->getMockBuilder(ClientInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->loggerMock = $this->getMockBuilder(LoggerInterface::class) ->disableOriginalConstructor() ->getMock(); - $objectManagerHelper = new ObjectManagerHelper($this); - $this->signUpCommand = $objectManagerHelper->getObject( - SignUpCommand::class, - [ - 'analyticsToken' => $this->analyticsTokenMock, - 'integrationManager' => $this->integrationManagerMock, - 'signUpRequest' => $this->signUpRequestMock - ] + $this->responseResolverMock = $this->getMockBuilder(ResponseResolver::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->signUpCommand = new SignUpCommand( + $this->analyticsTokenMock, + $this->integrationManagerMock, + $this->configMock, + $this->httpClientMock, + $this->loggerMock, + $this->responseResolverMock ); } @@ -79,13 +102,27 @@ public function testExecuteSuccess() $this->integrationManagerMock->expects($this->once()) ->method('activateIntegration') ->willReturn(true); - $this->signUpRequestMock->expects($this->once()) - ->method('call') - ->with('IntegrationToken') - ->willReturn('MAToken'); - $this->analyticsTokenMock->expects($this->once()) - ->method('storeToken') - ->with('MAToken') + $data = $this->getTestData(); + + $this->configMock->expects($this->any()) + ->method('getConfigDataValue') + ->willReturn($data['url']); + $this->integrationToken->expects($this->any()) + ->method('getData') + ->with('token') + ->willReturn($data['integration-token']); + $httpResponse = new \Zend_Http_Response(201, [], '{"access-token": "' . $data['access-token'] . '"}'); + $this->httpClientMock->expects($this->once()) + ->method('request') + ->with( + $data['method'], + $data['url'], + $data['body'] + ) + ->willReturn($httpResponse); + $this->responseResolverMock->expects($this->any()) + ->method('getResult') + ->with($httpResponse) ->willReturn(true); $this->assertTrue($this->signUpCommand->execute()); } @@ -96,14 +133,7 @@ public function testExecuteFailureCannotGenerateToken() ->method('generateToken') ->willReturn(false); $this->integrationManagerMock->expects($this->never()) - ->method('activateIntegration') - ->willReturn(true); - $this->signUpRequestMock->expects($this->never()) - ->method('call') - ->willReturn('MAToken'); - $this->analyticsTokenMock->expects($this->never()) - ->method('storeToken') - ->willReturn(true); + ->method('activateIntegration'); $this->assertFalse($this->signUpCommand->execute()); } @@ -115,12 +145,30 @@ public function testExecuteFailureResponseIsEmpty() $this->integrationManagerMock->expects($this->once()) ->method('activateIntegration') ->willReturn(true); - $this->signUpRequestMock->expects($this->once()) - ->method('call') - ->with('IntegrationToken') + $httpResponse = new \Zend_Http_Response(0, []); + $this->httpClientMock->expects($this->once()) + ->method('request') + ->willReturn($httpResponse); + $this->responseResolverMock->expects($this->any()) + ->method('getResult') ->willReturn(false); - $this->analyticsTokenMock->expects($this->never()) - ->method('storeToken'); $this->assertFalse($this->signUpCommand->execute()); } + + /** + * Returns test parameters for request. + * + * @return array + */ + private function getTestData() + { + return [ + 'url' => 'http://www.mystore.com', + 'access-token' => 'thisisaccesstoken', + 'integration-token' => 'thisisintegrationtoken', + 'headers' => [JsonConverter::CONTENT_TYPE_HEADER], + 'method' => \Magento\Framework\HTTP\ZendClient::POST, + 'body'=> ['token' => 'thisisintegrationtoken','url' => 'http://www.mystore.com'], + ]; + } } diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/SignUpRequestTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/SignUpRequestTest.php deleted file mode 100644 index 4b23e2c751b2c..0000000000000 --- a/app/code/Magento/Analytics/Test/Unit/Model/Connector/SignUpRequestTest.php +++ /dev/null @@ -1,226 +0,0 @@ -loggerMock = $this->getMockBuilder( - \Psr\Log\LoggerInterface::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->configMock = $this->getMockBuilder( - \Magento\Config\Model\Config::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->responseMock = $this->getMockBuilder( - \Zend_Http_Response::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->httpClientMock = $this->getMockBuilder( - \Magento\Analytics\Model\Connector\Http\ClientInterface::class - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->objectManagerHelper = - new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->subject = $this->objectManagerHelper->getObject( - \Magento\Analytics\Model\Connector\SignUpRequest::class, - [ - 'config' => $this->configMock, - 'httpClient' => $this->httpClientMock, - 'logger' => $this->loggerMock - ] - ); - } - - /** - * Returns test parameters for request. - * - * @return array - */ - private function getTestData() - { - return [ - 'url' => 'http://www.mystore.com', - 'access-token' => 'thisisaccesstoken', - 'integration-token' => 'thisisintegrationtoken', - 'headers' => ['Content-Type: application/json'], - 'method' => \Magento\Framework\HTTP\ZendClient::POST, - 'body'=> '{"token":"thisisintegrationtoken","url":"http:\/\/www.mystore.com"}', - ]; - } - - /** - * @return void - */ - public function testCallSuccess() - { - $data = $this->getTestData(); - - $this->configMock->expects($this->any()) - ->method('getConfigDataValue') - ->willReturn($data['url']); - - $this->httpClientMock->expects($this->once()) - ->method('request') - ->with( - $data['method'], - $data['url'], - $data['body'], - $data['headers'] - ) - ->willReturn($this->responseMock); - - $this->responseMock->expects($this->any()) - ->method('getStatus') - ->willReturn(201); - $this->responseMock->expects($this->any()) - ->method('getBody') - ->willReturn('{"access-token": "' . $data['access-token'] . '"}'); - - $this->assertEquals( - $data['access-token'], - $this->subject->call($data['integration-token']) - ); - } - - /** - * @return void - */ - public function testCallTransportFailure() - { - $data = $this->getTestData(); - - $this->configMock->expects($this->any()) - ->method('getConfigDataValue') - ->willReturn($data['url']); - - $this->httpClientMock->expects($this->once()) - ->method('request') - ->with( - $data['method'], - $data['url'], - $data['body'], - $data['headers'] - ) - ->willReturn(false); - - $this->assertFalse( - $this->subject->call($data['integration-token']) - ); - } - - /** - * @return void - */ - public function testCallNoAccessToken() - { - $data = $this->getTestData(); - - $this->configMock->expects($this->any()) - ->method('getConfigDataValue') - ->willReturn($data['url']); - - $this->httpClientMock->expects($this->once()) - ->method('request') - ->with( - $data['method'], - $data['url'], - $data['body'], - $data['headers'] - ) - ->willReturn($this->responseMock); - - $this->responseMock->expects($this->any()) - ->method('getStatus') - ->willReturn(409); - - $this->loggerMock->expects($this->once()) - ->method('warning'); - - $this->assertFalse( - $this->subject->call($data['integration-token']) - ); - } - - /** - * @return void - */ - public function testCallException() - { - $data = $this->getTestData(); - - $exception = new \Exception('Test Exception'); - - $this->configMock->expects($this->any()) - ->method('getConfigDataValue') - ->willReturn($data['url']); - - $this->httpClientMock->expects($this->once()) - ->method('request') - ->with( - $data['method'], - $data['url'], - $data['body'], - $data['headers'] - ) - ->willThrowException($exception); - - $this->loggerMock->expects($this->once()) - ->method('critical') - ->with($exception); - - $this->assertFalse( - $this->subject->call($data['integration-token']) - ); - } -} diff --git a/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php b/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php index c9cb6b8b0f712..c5f96a96b4432 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/Connector/UpdateCommandTest.php @@ -6,13 +6,14 @@ namespace Magento\Analytics\Test\Unit\Model\Connector; use Magento\Analytics\Model\AnalyticsToken; -use Magento\Analytics\Model\Connector\Http\ClientInterface; -use Magento\Analytics\Model\Connector\UpdateCommand; -use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin; -use Magento\Config\Model\Config; +use Magento\Analytics\Model\Connector\Http\ResponseResolver; use Magento\Framework\FlagManager; use Magento\Framework\HTTP\ZendClient; +use Magento\Config\Model\Config; use Psr\Log\LoggerInterface; +use Magento\Analytics\Model\Plugin\BaseUrlConfigPlugin; +use Magento\Analytics\Model\Connector\UpdateCommand; +use Magento\Analytics\Model\Connector\Http\ClientInterface; /** * Class SignUpCommandTest @@ -45,14 +46,14 @@ class UpdateCommandTest extends \PHPUnit_Framework_TestCase private $loggerMock; /** - * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var FlagManager|\PHPUnit_Framework_MockObject_MockObject */ - private $responseMock; + private $flagManagerMock; /** - * @var FlagManager|\PHPUnit_Framework_MockObject_MockObject + * @var ResponseResolver|\PHPUnit_Framework_MockObject_MockObject */ - private $flagManagerMock; + private $responseResolverMock; protected function setUp() { @@ -76,7 +77,7 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->responseMock = $this->getMockBuilder(\Zend_Http_Response::class) + $this->responseResolverMock = $this->getMockBuilder(ResponseResolver::class) ->disableOriginalConstructor() ->getMock(); @@ -85,7 +86,8 @@ protected function setUp() $this->httpClientMock, $this->configMock, $this->loggerMock, - $this->flagManagerMock + $this->flagManagerMock, + $this->responseResolverMock ); } @@ -94,7 +96,6 @@ public function testExecuteSuccess() $url = "old.localhost.com"; $configVal = "Config val"; $token = "Secret token!"; - $requestJson = sprintf('{"url":"%s","new-url":"%s","access-token":"%s"}', $url, $configVal, $token); $this->analyticsTokenMock->expects($this->once()) ->method('isTokenExist') ->willReturn(true); @@ -117,13 +118,16 @@ public function testExecuteSuccess() ->with( ZendClient::PUT, $configVal, - $requestJson, - ['Content-Type: application/json'] - )->willReturn($this->responseMock); - - $this->responseMock->expects($this->once()) - ->method('getStatus') - ->willReturn(201); + [ + 'url' => $url, + 'new-url' => $configVal, + 'access-token' => $token + ] + )->willReturn(new \Zend_Http_Response(200, [])); + + $this->responseResolverMock->expects($this->once()) + ->method('getResult') + ->willReturn(true); $this->assertTrue($this->updateCommand->execute()); } diff --git a/app/code/Magento/Analytics/Test/Unit/Model/LinkProviderTest.php b/app/code/Magento/Analytics/Test/Unit/Model/LinkProviderTest.php index 85d4eba2e588e..afda37962a3cb 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/LinkProviderTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/LinkProviderTest.php @@ -132,7 +132,7 @@ public function testGet() * @param string|null $fileInitializationVector * * @dataProvider fileNotReadyDataProvider - * @expectedException \Magento\Framework\Exception\NotFoundException + * @expectedException \Magento\Framework\Exception\NoSuchEntityException * @expectedExceptionMessage File is not ready yet. */ public function testFileNotReady($fileInfoPath, $fileInitializationVector) diff --git a/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php b/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php index c2a947362d1db..03fe7d968a7f5 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/NotificationTimeTest.php @@ -6,8 +6,8 @@ namespace Magento\Analytics\Test\Unit\Model; -use Magento\Framework\FlagManager; use Magento\Analytics\Model\NotificationTime; +use Magento\Framework\FlagManager; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; /** diff --git a/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php b/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php index 9e4defe195b32..90707b2db7e1a 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionStatusProviderTest.php @@ -8,7 +8,7 @@ use Magento\Analytics\Model\AnalyticsToken; use Magento\Analytics\Model\Config\Backend\Enabled\SubscriptionHandler; use Magento\Analytics\Model\SubscriptionStatusProvider; -use Magento\Config\App\Config\Type\System; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\FlagManager; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; @@ -18,9 +18,9 @@ class SubscriptionStatusProviderTest extends \PHPUnit_Framework_TestCase { /** - * @var System|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $systemConfigMock; + private $scopeConfigMock; /** * @var AnalyticsToken|\PHPUnit_Framework_MockObject_MockObject @@ -47,9 +47,8 @@ class SubscriptionStatusProviderTest extends \PHPUnit_Framework_TestCase */ protected function setUp() { - $this->systemConfigMock = $this->getMockBuilder(System::class) - ->disableOriginalConstructor() - ->getMock(); + $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class) + ->getMockForAbstractClass(); $this->analyticsTokenMock = $this->getMockBuilder(AnalyticsToken::class) ->disableOriginalConstructor() @@ -64,7 +63,7 @@ protected function setUp() $this->statusProvider = $this->objectManagerHelper->getObject( SubscriptionStatusProvider::class, [ - 'systemConfig' => $this->systemConfigMock, + 'scopeConfig' => $this->scopeConfigMock, 'analyticsToken' => $this->analyticsTokenMock, 'flagManager' => $this->flagManagerMock, ] @@ -76,9 +75,9 @@ public function testGetStatusShouldBeFailed() $this->analyticsTokenMock->expects($this->once()) ->method('isTokenExist') ->willReturn(false); - $this->systemConfigMock->expects($this->once()) - ->method('get') - ->with('default/analytics/subscription/enabled') + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with('analytics/subscription/enabled') ->willReturn(true); $this->expectFlagCounterReturn(null); @@ -90,9 +89,9 @@ public function testGetStatusShouldBePending() $this->analyticsTokenMock->expects($this->once()) ->method('isTokenExist') ->willReturn(false); - $this->systemConfigMock->expects($this->once()) - ->method('get') - ->with('default/analytics/subscription/enabled') + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with('analytics/subscription/enabled') ->willReturn(true); $this->expectFlagCounterReturn(45); @@ -104,18 +103,18 @@ public function testGetStatusShouldBeEnabled() $this->analyticsTokenMock->expects($this->once()) ->method('isTokenExist') ->willReturn(true); - $this->systemConfigMock->expects($this->once()) - ->method('get') - ->with('default/analytics/subscription/enabled') + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with('analytics/subscription/enabled') ->willReturn(true); $this->assertEquals(SubscriptionStatusProvider::ENABLED, $this->statusProvider->getStatus()); } public function testGetStatusShouldBeDisabled() { - $this->systemConfigMock->expects($this->once()) - ->method('get') - ->with('default/analytics/subscription/enabled') + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with('analytics/subscription/enabled') ->willReturn(false); $this->assertEquals(SubscriptionStatusProvider::DISABLED, $this->statusProvider->getStatus()); } diff --git a/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionTest.php b/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionTest.php deleted file mode 100644 index c0f2c18f822e1..0000000000000 --- a/app/code/Magento/Analytics/Test/Unit/Model/SubscriptionTest.php +++ /dev/null @@ -1,257 +0,0 @@ -configValueFactoryMock = $this->getMockBuilder(ValueFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->configValueMock = $this->getMockBuilder(Value::class) - ->disableOriginalConstructor() - ->setMethods(['setValue', 'setPath']) - ->getMock(); - - $this->configStructureMock = $this->getMockBuilder(SearchInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->configValueResourceMock = $this->getMockBuilder(AbstractDb::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->elementFieldMock = $this->getMockBuilder(Field::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->reinitableConfigMock = $this->getMockBuilder(ReinitableConfigInterface::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->subscriptionHandlerMock = $this->getMockBuilder(SubscriptionHandler::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->statusProviderMock = $this->getMockBuilder(SubscriptionStatusProvider::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->objectManagerHelper = new ObjectManagerHelper($this); - - $this->subscriptionModel = $this->objectManagerHelper->getObject( - SubscriptionModel::class, - [ - 'configValueFactory' => $this->configValueFactoryMock, - 'configStructure' => $this->configStructureMock, - 'configValueResource' => $this->configValueResourceMock, - 'reinitableConfig' => $this->reinitableConfigMock, - 'enabledConfigStructurePath' => $this->enableConfigStructurePath, - 'yesValueDropdown' => $this->yesValueDropdown, - 'subscriptionHandler' => $this->subscriptionHandlerMock, - 'statusProvider' => $this->statusProviderMock, - ] - ); - } - - /** - * @dataProvider enabledDataProvider - * - * @param boolean $backendModel - * @param string $configPath - * - * @return void - */ - public function testEnabled($backendModel, $configPath) - { - $this->configStructureMock - ->expects($this->once()) - ->method('getElement') - ->with($this->enableConfigStructurePath) - ->willReturn($this->elementFieldMock); - $this->elementFieldMock - ->expects($this->once()) - ->method('hasBackendModel') - ->willReturn($backendModel); - if ($backendModel) { - $this->elementFieldMock - ->expects($this->once()) - ->method('getBackendModel') - ->willReturn($this->configValueMock); - } else { - $this->configValueFactoryMock - ->expects($this->once()) - ->method('create') - ->willReturn($this->configValueMock); - } - $this->elementFieldMock - ->expects($this->once()) - ->method('getConfigPath') - ->willReturn($configPath); - $configPath = $configPath ?: $this->enableConfigStructurePath; - $this->configValueResourceMock - ->expects($this->once()) - ->method('load') - ->with($this->configValueMock, $configPath, 'path') - ->willReturnSelf(); - $this->configValueMock - ->expects($this->once()) - ->method('setValue') - ->with(1) - ->willReturnSelf(); - $this->configValueMock - ->expects($this->once()) - ->method('setPath') - ->with($configPath) - ->willReturnSelf(); - $this->configValueResourceMock - ->expects($this->once()) - ->method('save') - ->with($this->configValueMock) - ->willReturnSelf(); - $this->reinitableConfigMock - ->expects($this->once()) - ->method('reinit') - ->willReturnSelf(); - $this->assertTrue($this->subscriptionModel->enable()); - } - - /** - * @return array - */ - public function enabledDataProvider() - { - return [ - 'TestWithBackendModelWithoutConfigPath' => [true, null], - 'TestWithBackendModelWithConfigPath' => [true, $this->configPath], - 'TestWithoutBackendModelWithoutConfigPath' => [false, null], - 'TestWithoutBackendModelWithConfigPath' => [false, $this->configPath], - ]; - } - - /** - * @dataProvider retryDataProvider - * @param string $status - * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $invokedCount - * @return void - */ - public function testRetry($status, \PHPUnit_Framework_MockObject_Matcher_InvokedCount $invokedCount) - { - $this->statusProviderMock - ->expects($this->once()) - ->method('getStatus') - ->with() - ->willReturn($status); - $this->subscriptionHandlerMock - ->expects(clone $invokedCount) - ->method('processEnabled') - ->with() - ->willReturn(true); - $this->reinitableConfigMock - ->expects(clone $invokedCount) - ->method('reinit') - ->with() - ->willReturnSelf(); - $this->assertTrue($this->subscriptionModel->retry()); - } - - /** - * @return array - */ - public function retryDataProvider() - { - return [ - 'Status Pending' => [SubscriptionStatusProvider::PENDING, $this->never()], - 'Status Failed' => [SubscriptionStatusProvider::FAILED, $this->once()], - 'Status Disabled' => [SubscriptionStatusProvider::DISABLED, $this->never()], - ]; - } -} diff --git a/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/FromAssemblerTest.php b/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/FromAssemblerTest.php index b6c596f7e7e24..cbabac5613a8b 100644 --- a/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/FromAssemblerTest.php +++ b/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/FromAssemblerTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Analytics\Test\Unit\ReportXml\DB\Assembler; +use Magento\Framework\App\ResourceConnection; + /** * A unit test for testing of the 'from' assembler. */ @@ -35,6 +37,11 @@ class FromAssemblerTest extends \PHPUnit_Framework_TestCase */ private $columnsResolverMock; + /** + * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + */ + private $resourceConnection; + /** * @return void */ @@ -61,6 +68,10 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); + $this->resourceConnection = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -68,45 +79,43 @@ protected function setUp() \Magento\Analytics\ReportXml\DB\Assembler\FromAssembler::class, [ 'nameResolver' => $this->nameResolverMock, - 'columnsResolver' => $this->columnsResolverMock + 'columnsResolver' => $this->columnsResolverMock, + 'resourceConnection' => $this->resourceConnection, ] ); } /** + * @dataProvider assembleDataProvider + * @param array $queryConfig + * @param string $tableName * @return void */ - public function testAssemble() + public function testAssemble(array $queryConfig, $tableName) { - $queryConfigMock = [ - 'source' => [ - 'name' => 'sales_order', - 'alias' => 'sales', - 'attribute' => [ - [ - 'name' => 'entity_id' - ] - ] - ] - ]; - $this->nameResolverMock->expects($this->any()) ->method('getAlias') - ->with($queryConfigMock['source']) - ->willReturn($queryConfigMock['source']['alias']); + ->with($queryConfig['source']) + ->willReturn($queryConfig['source']['alias']); - $this->nameResolverMock->expects($this->any()) + $this->nameResolverMock->expects($this->once()) ->method('getName') - ->with($queryConfigMock['source']) - ->willReturn($queryConfigMock['source']['name']); + ->with($queryConfig['source']) + ->willReturn($queryConfig['source']['name']); + + $this->resourceConnection + ->expects($this->once()) + ->method('getTableName') + ->with($queryConfig['source']['name']) + ->willReturn($tableName); $this->selectBuilderMock->expects($this->once()) ->method('setFrom') - ->with([$queryConfigMock['source']['alias'] => $queryConfigMock['source']['name']]); + ->with([$queryConfig['source']['alias'] => $tableName]); $this->columnsResolverMock->expects($this->once()) ->method('getColumns') - ->with($this->selectBuilderMock, $queryConfigMock['source']) + ->with($this->selectBuilderMock, $queryConfig['source']) ->willReturn(['entity_id' => 'sales.entity_id']); $this->selectBuilderMock->expects($this->once()) @@ -115,7 +124,44 @@ public function testAssemble() $this->assertEquals( $this->selectBuilderMock, - $this->subject->assemble($this->selectBuilderMock, $queryConfigMock) + $this->subject->assemble($this->selectBuilderMock, $queryConfig) ); } + + /** + * @return array + */ + public function assembleDataProvider() + { + return [ + 'Tables without prefixes' => [ + [ + 'source' => [ + 'name' => 'sales_order', + 'alias' => 'sales', + 'attribute' => [ + [ + 'name' => 'entity_id' + ] + ], + ], + ], + 'sales_order', + ], + 'Tables with prefixes' => [ + [ + 'source' => [ + 'name' => 'sales_order', + 'alias' => 'sales', + 'attribute' => [ + [ + 'name' => 'entity_id' + ] + ], + ], + ], + 'pref_sales_order', + ] + ]; + } } diff --git a/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/JoinAssemblerTest.php b/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/JoinAssemblerTest.php index 11584a501457a..b913689513ce5 100644 --- a/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/JoinAssemblerTest.php +++ b/app/code/Magento/Analytics/Test/Unit/ReportXml/DB/Assembler/JoinAssemblerTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Analytics\Test\Unit\ReportXml\DB\Assembler; +use Magento\Framework\App\ResourceConnection; + /** * A unit test for testing of the 'join' assembler. */ @@ -40,6 +42,11 @@ class JoinAssemblerTest extends \PHPUnit_Framework_TestCase */ private $conditionResolverMock; + /** + * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + */ + private $resourceConnection; + /** * @return void */ @@ -78,6 +85,10 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); + $this->resourceConnection = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -86,7 +97,8 @@ protected function setUp() [ 'conditionResolver' => $this->conditionResolverMock, 'nameResolver' => $this->nameResolverMock, - 'columnsResolver' => $this->columnsResolverMock + 'columnsResolver' => $this->columnsResolverMock, + 'resourceConnection' => $this->resourceConnection, ] ); } @@ -118,24 +130,15 @@ public function testAssembleEmpty() /** * @param array $queryConfigMock - * - * @dataProvider assembleNotEmptyDataProvider + * @param array $joinsMock + * @param array $tablesMapping * @return void + * @dataProvider assembleNotEmptyDataProvider */ - public function testAssembleNotEmpty(array $queryConfigMock) + public function testAssembleNotEmpty(array $queryConfigMock, array $joinsMock, array $tablesMapping) { $filtersMock = []; - $joinsMock = [ - 'billing' => [ - 'link-type' => 'left', - 'table' => [ - 'billing' => 'sales_order_address' - ], - 'condition' => '(billing.parent_id = `sales`.`entity_id`)' - ] - ]; - $this->nameResolverMock->expects($this->at(0)) ->method('getAlias') ->with($queryConfigMock['source']) @@ -144,11 +147,16 @@ public function testAssembleNotEmpty(array $queryConfigMock) ->method('getAlias') ->with($queryConfigMock['source']['link-source'][0]) ->willReturn($queryConfigMock['source']['link-source'][0]['alias']); - $this->nameResolverMock->expects($this->any()) + $this->nameResolverMock->expects($this->once()) ->method('getName') ->with($queryConfigMock['source']['link-source'][0]) ->willReturn($queryConfigMock['source']['link-source'][0]['name']); + $this->resourceConnection + ->expects($this->any()) + ->method('getTableName') + ->willReturnOnConsecutiveCalls(...array_values($tablesMapping)); + $this->conditionResolverMock->expects($this->at(0)) ->method('getFilter') ->with( @@ -254,7 +262,17 @@ public function assembleNotEmptyDataProvider() ] ] ] - ] + ], + [ + 'billing' => [ + 'link-type' => 'left', + 'table' => [ + 'billing' => 'pref_sales_order_address' + ], + 'condition' => '(billing.parent_id = `sales`.`entity_id`)' + ] + ], + ['sales_order_address' => 'pref_sales_order_address'] ] ]; } diff --git a/app/code/Magento/Analytics/etc/di.xml b/app/code/Magento/Analytics/etc/di.xml index 3b11b3c6ff1a8..a23c1ad957ea6 100644 --- a/app/code/Magento/Analytics/etc/di.xml +++ b/app/code/Magento/Analytics/etc/di.xml @@ -13,6 +13,7 @@ + @@ -29,7 +30,7 @@ - + Magento\Config\Model\ResourceModel\Config\Data @@ -147,4 +148,54 @@ + + + + \Magento\Analytics\Model\Connector\ResponseHandler\SignUp + + + + + + + Magento\Analytics\Model\Connector\ResponseHandler\Update + Magento\Analytics\Model\Connector\ResponseHandler\ReSignUp + + + + + + + Magento\Analytics\Model\Connector\ResponseHandler\OTP + Magento\Analytics\Model\Connector\ResponseHandler\ReSignUp + + + + + + + Magento\Analytics\Model\Connector\ResponseHandler\ReSignUp + + + + + + SignUpResponseResolver + + + + + UpdateResponseResolver + + + + + OtpResponseResolver + + + + + NotifyDataChangedResponseResolver + + diff --git a/app/code/Magento/Analytics/etc/module.xml b/app/code/Magento/Analytics/etc/module.xml index b0bd51f7ffa36..32ee5d23a4d86 100644 --- a/app/code/Magento/Analytics/etc/module.xml +++ b/app/code/Magento/Analytics/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/app/code/Magento/Catalog/Setup/UpgradeSchema.php b/app/code/Magento/Catalog/Setup/UpgradeSchema.php index 46e367adfb1ea..80a3f04d19fac 100755 --- a/app/code/Magento/Catalog/Setup/UpgradeSchema.php +++ b/app/code/Magento/Catalog/Setup/UpgradeSchema.php @@ -65,6 +65,7 @@ public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $con if (version_compare($context->getVersion(), '2.2.0', '<')) { $this->addProductEavIndexReplicaTables($setup); + $this->addPathKeyToCategoryEntityTableIfNotExists($setup); // By adding 'catalog_product_index_price_replica' we provide separation of tables // used for indexation write and read operations and affected models. $this->addReplicaTable( @@ -470,6 +471,38 @@ private function recreateCatalogCategoryProductIndexTmpTable(SchemaSetupInterfac $setup->getConnection()->createTable($table); } + /** + * Add key for the path field if not exists + * significantly improves category tree performance + * + * @param SchemaSetupInterface $setup + * @return void + */ + private function addPathKeyToCategoryEntityTableIfNotExists(SchemaSetupInterface $setup) + { + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface + */ + $connection = $setup->getConnection(); + $tableName = $setup->getTable('catalog_category_entity'); + + $keyName = $setup->getIdxName( + $tableName, + ['path'], + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX + ); + + $existingKeys = $connection->getIndexList($tableName); + if (!array_key_exists($keyName, $existingKeys)) { + $connection->addIndex( + $tableName, + $keyName, + ['path'], + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_INDEX + ); + } + } + /** * Add the replica table for existing one. * diff --git a/app/code/Magento/CatalogAnalytics/etc/module.xml b/app/code/Magento/CatalogAnalytics/etc/module.xml index c0cf369690b63..7974598e17a59 100644 --- a/app/code/Magento/CatalogAnalytics/etc/module.xml +++ b/app/code/Magento/CatalogAnalytics/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php index 70d4883fe151f..78a60e29e444e 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php @@ -125,13 +125,23 @@ public function lockProductsStock($productIds, $websiteId) return []; } $itemTable = $this->getTable('cataloginventory_stock_item'); - $productTable = $this->getTable('catalog_product_entity'); $select = $this->getConnection()->select()->from(['si' => $itemTable]) - ->join(['p' => $productTable], 'p.entity_id=si.product_id', ['type_id']) ->where('website_id=?', $websiteId) ->where('product_id IN(?)', $productIds) ->forUpdate(true); - return $this->getConnection()->fetchAll($select); + + $productTable = $this->getTable('catalog_product_entity'); + $selectProducts = $this->getConnection()->select()->from(['p' => $productTable], []) + ->where('entity_id IN (?)', $productIds) + ->columns( + [ + 'product_id' => 'entity_id', + 'type_id' => 'type_id' + ] + ); + $this->getConnection()->query($select); + + return $this->getConnection()->fetchAll($selectProducts); } /** diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/StockTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/StockTest.php new file mode 100644 index 0000000000000..3ca3c24e41bdb --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/StockTest.php @@ -0,0 +1,99 @@ +contextMock = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock(); + $this->resourceMock = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->contextMock->expects($this->once())->method('getResources')->willReturn($this->resourceMock); + + $this->stockModel = (new ObjectManager($this))->getObject( + Stock::class, + [ + 'context' => $this->contextMock + ] + ); + } + + public function testLockProductsStock() + { + $productIds = [1, 2]; + $websiteId = 1; + $itemTable = 'item_table'; + $productTable = 'product_table'; + + $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)->getMock(); + $this->resourceMock->method('getConnection')->will($this->returnValue($connectionMock)); + + $this->resourceMock->method('getTableName') + ->withConsecutive(['cataloginventory_stock_item'], ['catalog_product_entity']) + ->willReturnOnConsecutiveCalls($itemTable, $productTable); + + $selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->disableOriginalConstructor() + ->getMock(); + + $selectProductsMock = clone $selectMock; + + $selectMock->expects($this->once())->method('forUpdate')->with(true)->willReturnSelf(); + $selectMock->expects($this->once())->method('from')->with(['si' => $itemTable])->willReturnSelf(); + $selectMock->expects($this->exactly(2)) + ->method('where') + ->withConsecutive(['website_id=?', $websiteId], ['product_id IN(?)', $productIds]) + ->willReturnSelf(); + $connectionMock->expects($this->exactly(2)) + ->method('select') + ->willReturnOnConsecutiveCalls($selectMock, $selectProductsMock); + + $selectProductsMock->expects($this->once())->method('from')->with(['p' => $productTable], [])->willReturnSelf(); + $selectProductsMock->expects($this->once())->method('where') + ->with('entity_id IN (?)', $productIds) + ->willReturnSelf(); + $selectProductsMock->expects($this->once())->method('columns')->willReturnSelf(); + + $connectionMock->expects($this->once())->method('query')->with($selectMock); + $connectionMock->expects($this->once())->method('fetchAll')->with($selectProductsMock)->willReturn([]); + + $this->assertEquals([], $this->stockModel->lockProductsStock($productIds, $websiteId)); + } + + public function testLockNoProductsStock() + { + $productIds = []; + $websiteId = 1; + + $this->assertEquals([], $this->stockModel->lockProductsStock($productIds, $websiteId)); + } +} diff --git a/app/code/Magento/Config/Model/Config/Source/Enabledisable.php b/app/code/Magento/Config/Model/Config/Source/Enabledisable.php index a9a79827a17bb..acc2003f58665 100644 --- a/app/code/Magento/Config/Model/Config/Source/Enabledisable.php +++ b/app/code/Magento/Config/Model/Config/Source/Enabledisable.php @@ -5,13 +5,29 @@ */ namespace Magento\Config\Model\Config\Source; +/** + * Source model for element with enable and disable variants. + */ class Enabledisable implements \Magento\Framework\Option\ArrayInterface { + /** + * Value which equal Enable for Enabledisable dropdown. + */ + const ENABLE_VALUE = 1; + + /** + * Value which equal Disable for Enabledisable dropdown. + */ + const DISABLE_VALUE = 0; + /** * @return array */ public function toOptionArray() { - return [['value' => 1, 'label' => __('Enable')], ['value' => 0, 'label' => __('Disable')]]; + return [ + ['value' => self::ENABLE_VALUE, 'label' => __('Enable')], + ['value' => self::DISABLE_VALUE, 'label' => __('Disable')], + ]; } } diff --git a/app/code/Magento/Config/Model/PreparedValueFactory.php b/app/code/Magento/Config/Model/PreparedValueFactory.php index 14555096336c6..dd19be9af29a2 100644 --- a/app/code/Magento/Config/Model/PreparedValueFactory.php +++ b/app/code/Magento/Config/Model/PreparedValueFactory.php @@ -88,10 +88,14 @@ public function create($path, $value, $scope, $scopeCode = null) $structure = $this->structureFactory->create(); /** @var Structure\ElementInterface $field */ $field = $structure->getElement($path); + $configPath = $path; /** @var string $backendModelName */ - $backendModelName = $field instanceof Structure\Element\Field && $field->hasBackendModel() - ? $field->getData()['backend_model'] - : ValueInterface::class; + if ($field instanceof Structure\Element\Field && $field->hasBackendModel()) { + $backendModelName = $field->getData()['backend_model']; + $configPath = $field->getConfigPath() ?: $path; + } else { + $backendModelName = ValueInterface::class; + } /** @var ValueInterface $backendModel */ $backendModel = $this->valueFactory->create( $backendModelName, @@ -106,7 +110,7 @@ public function create($path, $value, $scope, $scopeCode = null) $scopeId = $scopeResolver->getScope($scopeCode)->getId(); } - $backendModel->setPath($path); + $backendModel->setPath($configPath); $backendModel->setScope($scope); $backendModel->setScopeId($scopeId); $backendModel->setValue($value); diff --git a/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php b/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php index 743ec0d991b32..5f7f7ed3532ab 100644 --- a/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/PreparedValueFactoryTest.php @@ -116,6 +116,7 @@ protected function setUp() /** * @param string $path + * @param string|null $configPath * @param string $value * @param string $scope * @param string|int|null $scopeCode @@ -124,6 +125,7 @@ protected function setUp() */ public function testCreate( $path, + $configPath, $value, $scope, $scopeCode, @@ -152,12 +154,15 @@ public function testCreate( $this->fieldMock->expects($this->once()) ->method('hasBackendModel') ->willReturn(true); + $this->fieldMock + ->method('getConfigPath') + ->willReturn($configPath); $this->valueFactoryMock->expects($this->once()) ->method('create') ->willReturn($this->valueMock); $this->valueMock->expects($this->once()) ->method('setPath') - ->with($path) + ->with($configPath ?: $path) ->willReturnSelf(); $this->valueMock->expects($this->once()) ->method('setScope') @@ -186,6 +191,15 @@ public function createDataProvider() return [ 'standard flow' => [ '/some/path', + null, + 'someValue', + 'someScope', + 'someScopeCode', + 1, + ], + 'standard flow with custom config path' => [ + '/some/path', + '/custom/config_path', 'someValue', 'someScope', 'someScopeCode', @@ -193,6 +207,7 @@ public function createDataProvider() ], 'default scope flow' => [ '/some/path', + null, 'someValue', ScopeInterface::SCOPE_DEFAULT, null, diff --git a/app/code/Magento/CustomerAnalytics/etc/module.xml b/app/code/Magento/CustomerAnalytics/etc/module.xml index 8463a9bfeb882..adc4f8dd849c2 100644 --- a/app/code/Magento/CustomerAnalytics/etc/module.xml +++ b/app/code/Magento/CustomerAnalytics/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/app/code/Magento/QuoteAnalytics/etc/module.xml b/app/code/Magento/QuoteAnalytics/etc/module.xml index b92121e531695..d72e36b748748 100644 --- a/app/code/Magento/QuoteAnalytics/etc/module.xml +++ b/app/code/Magento/QuoteAnalytics/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/app/code/Magento/ReviewAnalytics/etc/module.xml b/app/code/Magento/ReviewAnalytics/etc/module.xml index 1bac42c525334..65df87bac4af1 100644 --- a/app/code/Magento/ReviewAnalytics/etc/module.xml +++ b/app/code/Magento/ReviewAnalytics/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/app/code/Magento/SalesAnalytics/etc/module.xml b/app/code/Magento/SalesAnalytics/etc/module.xml index 437b88e55a7aa..7a15075a4bc21 100644 --- a/app/code/Magento/SalesAnalytics/etc/module.xml +++ b/app/code/Magento/SalesAnalytics/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/app/code/Magento/SalesAnalytics/etc/reports.xml b/app/code/Magento/SalesAnalytics/etc/reports.xml index 058bf3449db16..bb6bdb800e9bf 100644 --- a/app/code/Magento/SalesAnalytics/etc/reports.xml +++ b/app/code/Magento/SalesAnalytics/etc/reports.xml @@ -26,6 +26,8 @@ + + diff --git a/app/code/Magento/WishlistAnalytics/etc/module.xml b/app/code/Magento/WishlistAnalytics/etc/module.xml index a59299249e0a5..159ed86ee171a 100644 --- a/app/code/Magento/WishlistAnalytics/etc/module.xml +++ b/app/code/Magento/WishlistAnalytics/etc/module.xml @@ -6,7 +6,7 @@ */ --> - + diff --git a/dev/tests/integration/phpunit.xml.dist b/dev/tests/integration/phpunit.xml.dist index 742eb1d940b2f..7820eb746da5d 100644 --- a/dev/tests/integration/phpunit.xml.dist +++ b/dev/tests/integration/phpunit.xml.dist @@ -47,7 +47,7 @@ - + diff --git a/dev/tests/integration/testsuite/Magento/Analytics/Model/Connector/Http/ReSignUpResponseResolverTest.php b/dev/tests/integration/testsuite/Magento/Analytics/Model/Connector/Http/ReSignUpResponseResolverTest.php new file mode 100644 index 0000000000000..f69c751e1357f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Analytics/Model/Connector/Http/ReSignUpResponseResolverTest.php @@ -0,0 +1,140 @@ +otpResponseResolver = Bootstrap::getObjectManager()->get( + 'OtpResponseResolver' + ); + $this->updateResponseResolver = Bootstrap::getObjectManager()->get( + 'UpdateResponseResolver' + ); + $this->converter = Bootstrap::getObjectManager()->get(ConverterInterface::class); + } + + /** + * @magentoDataFixture Magento/Analytics/_files/enabled_subscription_with_invalid_token.php + */ + public function testReSignUpOnOtp() + { + $body = $this->converter->toBody(['test' => '42']); + $retryResponse = new \Zend_Http_Response(401, [$this->converter->getContentTypeHeader()], $body); + $this->otpResponseResolver->getResult($retryResponse); + $this->assertCronWasSet(); + } + + /** + * @magentoDataFixture Magento/Analytics/_files/enabled_subscription_with_invalid_token.php + */ + public function testReSignOnOtpWasNotCalled() + { + $body = $this->converter->toBody(['test' => '42']); + $successResponse = new \Zend_Http_Response(201, [$this->converter->getContentTypeHeader()], $body); + $this->otpResponseResolver->getResult($successResponse); + $this->assertCronWasNotSet(); + } + + /** + * @magentoDataFixture Magento/Analytics/_files/enabled_subscription_with_invalid_token.php + */ + public function testReSignUpOnUpdateWasCalled() + { + $body = $this->converter->toBody(['test' => '42']); + $retryResponse = new \Zend_Http_Response(401, [$this->converter->getContentTypeHeader()], $body); + $this->updateResponseResolver->getResult($retryResponse); + $this->assertCronWasSet(); + } + + /** + * @magentoDataFixture Magento/Analytics/_files/enabled_subscription_with_invalid_token.php + */ + public function testReSignUpOnUpdateWasnotCalled() + { + $body = $this->converter->toBody(['test' => '42']); + $successResponse = new \Zend_Http_Response(201, [$this->converter->getContentTypeHeader()], $body); + $this->updateResponseResolver->getResult($successResponse); + $this->assertCronWasNotSet(); + } + + /** + * @return string|null + */ + private function getSubscribeSchedule() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** + * @var $scopeConfig ScopeConfigInterface + */ + $scopeConfig = $objectManager->get(ScopeConfigInterface::class); + + return $scopeConfig->getValue( + SubscriptionHandler::CRON_STRING_PATH, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT, + 0 + ); + } + + /** + * @return int|null + */ + private function getAttemptFlag() + { + $objectManager = Bootstrap::getObjectManager(); + /** + * @var $flagManager FlagManager + */ + $flagManager = $objectManager->get(FlagManager::class); + + return $flagManager->getFlagData(SubscriptionHandler::ATTEMPTS_REVERSE_COUNTER_FLAG_CODE); + } + + /** + * @return void + */ + private function assertCronWasSet() + { + $this->assertEquals('0 * * * *', $this->getSubscribeSchedule()); + $this->assertGreaterThan(1, $this->getAttemptFlag()); + } + + /** + * @return void + */ + private function assertCronWasNotSet() + { + $this->assertNull($this->getSubscribeSchedule()); + $this->assertNull($this->getAttemptFlag()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Analytics/_files/enabled_subscription_with_invalid_token.php b/dev/tests/integration/testsuite/Magento/Analytics/_files/enabled_subscription_with_invalid_token.php new file mode 100644 index 0000000000000..0106bf6f1bdac --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Analytics/_files/enabled_subscription_with_invalid_token.php @@ -0,0 +1,29 @@ +get(\Magento\Framework\App\Config\Storage\WriterInterface::class); + +$configWriter->delete(SubscriptionHandler::CRON_STRING_PATH); +$configWriter->save('analytics/subscription/enabled', 1); + +/** + * @var $analyticsToken \Magento\Analytics\Model\AnalyticsToken + */ +$analyticsToken = $objectManager->get(\Magento\Analytics\Model\AnalyticsToken::class); +$analyticsToken->storeToken('42'); + +/** + * @var $flagManager \Magento\Framework\FlagManager + */ +$flagManager = $objectManager->get(\Magento\Framework\FlagManager::class); + +$flagManager->deleteFlag(SubscriptionHandler::ATTEMPTS_REVERSE_COUNTER_FLAG_CODE); diff --git a/dev/tests/integration/testsuite/Magento/Analytics/_files/enabled_subscription_with_invalid_token_rollback.php b/dev/tests/integration/testsuite/Magento/Analytics/_files/enabled_subscription_with_invalid_token_rollback.php new file mode 100644 index 0000000000000..3fd3e21e282e0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Analytics/_files/enabled_subscription_with_invalid_token_rollback.php @@ -0,0 +1,29 @@ +get(\Magento\Framework\App\Config\Storage\WriterInterface::class); + +$configWriter->delete(SubscriptionHandler::CRON_STRING_PATH); +$configWriter->save('analytics/subscription/enabled', 0); + +/** + * @var $analyticsToken \Magento\Analytics\Model\AnalyticsToken + */ +$analyticsToken = $objectManager->get(\Magento\Analytics\Model\AnalyticsToken::class); +$analyticsToken->storeToken(null); + +/** + * @var $flagManager \Magento\Framework\FlagManager + */ +$flagManager = $objectManager->get(\Magento\Framework\FlagManager::class); + +$flagManager->deleteFlag(SubscriptionHandler::ATTEMPTS_REVERSE_COUNTER_FLAG_CODE); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php index 5c253c0ac69e3..21ef8e52a2eb6 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php @@ -125,7 +125,7 @@ public function testGetParentIds() public function testGetChildren() { $this->_model->load(3); - $this->assertEquals('4,13', $this->_model->getChildren()); + $this->assertEquals(array_diff([4, 13], explode(',', $this->_model->getChildren())), []); } public function testGetPathInStore()