diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAdminWithCredentialsActionGroup.xml deleted file mode 100644 index 15f6852b4767c..0000000000000 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAdminActionGroup.xml deleted file mode 100644 index a2d024bee8b74..0000000000000 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAdminActionGroup.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - diff --git a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php index 7819f2f017a01..19c4e7a7327d0 100644 --- a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php +++ b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php @@ -11,28 +11,27 @@ use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\App\CacheInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -/** - * Class CanViewNotificationTest - */ -class CanViewNotificationTest extends \PHPUnit\Framework\TestCase +class CanViewNotificationTest extends TestCase { /** @var CanViewNotification */ private $canViewNotification; - /** @var Logger|\PHPUnit_Framework_MockObject_MockObject */ + /** @var Logger|MockObject */ private $viewerLoggerMock; - /** @var ProductMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var ProductMetadataInterface|MockObject */ private $productMetadataMock; - /** @var Log|\PHPUnit_Framework_MockObject_MockObject */ + /** @var Log|MockObject */ private $logMock; - /** @var $cacheStorageMock \PHPUnit_Framework_MockObject_MockObject|CacheInterface */ + /** @var $cacheStorageMock MockObject|CacheInterface */ private $cacheStorageMock; - public function setUp() + protected function setUp(): void { $this->cacheStorageMock = $this->getMockBuilder(CacheInterface::class) ->getMockForAbstractClass(); diff --git a/app/code/Magento/Amqp/Test/Unit/Setup/ConfigOptionsListTest.php b/app/code/Magento/Amqp/Test/Unit/Setup/ConfigOptionsListTest.php index 5b19ba055d059..57d9372dc0f0d 100644 --- a/app/code/Magento/Amqp/Test/Unit/Setup/ConfigOptionsListTest.php +++ b/app/code/Magento/Amqp/Test/Unit/Setup/ConfigOptionsListTest.php @@ -6,12 +6,16 @@ namespace Magento\Amqp\Test\Unit\Setup; +use Magento\Amqp\Setup\ConnectionValidator; +use Magento\Framework\Config\Data\ConfigData; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Amqp\Setup\ConfigOptionsList; use Magento\Framework\Setup\Option\TextConfigOption; use Magento\Framework\App\DeploymentConfig; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class ConfigOptionsListTest extends \PHPUnit\Framework\TestCase +class ConfigOptionsListTest extends TestCase { /** * @var ObjectManager @@ -24,12 +28,12 @@ class ConfigOptionsListTest extends \PHPUnit\Framework\TestCase private $model; /** - * @var \Magento\Amqp\Setup\ConnectionValidator|\PHPUnit_Framework_MockObject_MockObject + * @var ConnectionValidator|MockObject */ private $connectionValidatorMock; /** - * @var \Magento\Framework\App\DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject + * @var DeploymentConfig|MockObject */ private $deploymentConfigMock; @@ -38,7 +42,7 @@ class ConfigOptionsListTest extends \PHPUnit\Framework\TestCase */ private $options; - protected function setUp() + protected function setUp(): void { $this->options = [ ConfigOptionsList::INPUT_KEY_QUEUE_AMQP_HOST => 'host', @@ -51,18 +55,18 @@ protected function setUp() ]; $this->objectManager = new ObjectManager($this); - $this->connectionValidatorMock = $this->getMockBuilder(\Magento\Amqp\Setup\ConnectionValidator::class) + $this->connectionValidatorMock = $this->getMockBuilder(ConnectionValidator::class) ->disableOriginalConstructor() ->setMethods([]) ->getMock(); - $this->deploymentConfigMock = $this->getMockBuilder(\Magento\Framework\App\DeploymentConfig::class) + $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) ->disableOriginalConstructor() ->setMethods([]) ->getMock(); $this->model = $this->objectManager->getObject( - \Magento\Amqp\Setup\ConfigOptionsList::class, + ConfigOptionsList::class, [ 'connectionValidator' => $this->connectionValidatorMock, ] @@ -135,9 +139,9 @@ public function testCreateConfig($options, $expectedConfigData) $result = $this->model->createConfig($options, $this->deploymentConfigMock); $this->assertInternalType('array', $result); $this->assertNotEmpty($result); - /** @var \Magento\Framework\Config\Data\ConfigData $configData */ + /** @var ConfigData $configData */ $configData = $result[0]; - $this->assertInstanceOf(\Magento\Framework\Config\Data\ConfigData::class, $configData); + $this->assertInstanceOf(ConfigData::class, $configData); $this->assertEquals($expectedConfigData, $configData->getData()); } diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminAdvancedReportingButtonTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminAdvancedReportingButtonTest.xml index 5da7ccd3c9823..cbcbb3a5dd64c 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminAdvancedReportingButtonTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminAdvancedReportingButtonTest.xml @@ -22,7 +22,7 @@ - + diff --git a/app/code/Magento/Analytics/etc/di.xml b/app/code/Magento/Analytics/etc/di.xml index cdb42f18718b7..e06be2fb4d500 100644 --- a/app/code/Magento/Analytics/etc/di.xml +++ b/app/code/Magento/Analytics/etc/di.xml @@ -161,15 +161,13 @@ payment/banktransfer/active payment/cashondelivery/title payment/cashondelivery/active - payment/authorizenet_directpost/title - payment/authorizenet_directpost/active - payment/paypal_billing_agreement/title - payment/paypal_billing_agreement/active - payment/braintree/title - payment/braintree/active - payment/braintree_paypal/title - payment/braintree_paypal/active - analytics/general/vertical + payment/paypal_billing_agreement/title + payment/paypal_billing_agreement/active + payment/braintree/title + payment/braintree/active + payment/braintree_paypal/title + payment/braintree_paypal/active + analytics/general/vertical diff --git a/app/code/Magento/AsynchronousOperations/composer.json b/app/code/Magento/AsynchronousOperations/composer.json index 4ac67ac6aa645..8a7a4f07a96cd 100644 --- a/app/code/Magento/AsynchronousOperations/composer.json +++ b/app/code/Magento/AsynchronousOperations/composer.json @@ -6,6 +6,7 @@ }, "require": { "magento/framework": "*", + "magento/framework-message-queue": "*", "magento/framework-bulk": "*", "magento/module-authorization": "*", "magento/module-backend": "*", diff --git a/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/FraudDetails.php b/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/FraudDetails.php deleted file mode 100644 index c693ebe95d52b..0000000000000 --- a/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/FraudDetails.php +++ /dev/null @@ -1,60 +0,0 @@ -registry = $registry; - parent::__construct($context, $data); - } - - /** - * Return payment method model - * - * @return \Magento\Sales\Model\Order\Payment - */ - public function getPayment() - { - $order = $this->registry->registry('current_order'); - return $order->getPayment(); - } - - /** - * Produce and return the block's HTML output - * - * @return string - */ - protected function _toHtml() - { - return ($this->getPayment()->getMethod() === Directpost::METHOD_CODE) ? parent::_toHtml() : ''; - } -} diff --git a/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/PaymentDetails.php b/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/PaymentDetails.php deleted file mode 100644 index 23034270640dd..0000000000000 --- a/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/PaymentDetails.php +++ /dev/null @@ -1,29 +0,0 @@ -dataFactory = $dataFactory; - $this->messageManager = $messageManager; - parent::__construct($context, $registry, $data); - } - - /** - * Get helper data - * - * @param string $area - * @return \Magento\Authorizenet\Helper\Backend\Data|\Magento\Authorizenet\Helper\Data - */ - public function getHelper($area) - { - return $this->dataFactory->create($area); - } - - /** - * {inheritdoc} - */ - protected function _beforeToHtml() - { - $this->addSuccessMessage(); - return parent::_beforeToHtml(); - } - - /** - * Add success message - * - * @return void - */ - private function addSuccessMessage() - { - $params = $this->getParams(); - if (isset($params['redirect_parent'])) { - $this->messageManager->addSuccess(__('You created the order.')); - } - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php deleted file mode 100644 index f71314613fc1f..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php +++ /dev/null @@ -1,20 +0,0 @@ -helper = $helper; - parent::__construct($context, $productHelper, $escaper, $resultPageFactory, $resultForwardFactory); - } - - /** - * Send request to authorize.net - * - * @return void - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function execute() - { - $paymentParam = $this->getRequest()->getParam('payment'); - $controller = $this->getRequest()->getParam('controller'); - $this->getRequest()->setPostValue('collect_shipping_rates', 1); - $this->_processActionData('save'); - - //get confirmation by email flag - $orderData = $this->getRequest()->getPost('order'); - $sendConfirmationFlag = 0; - if ($orderData) { - $sendConfirmationFlag = !empty($orderData['send_confirmation']) ? 1 : 0; - } else { - $orderData = []; - } - - if (isset($paymentParam['method'])) { - $result = []; - //create order partially - $this->_getOrderCreateModel()->setPaymentData($paymentParam); - $this->_getOrderCreateModel()->getQuote()->getPayment()->addData($paymentParam); - - $orderData['send_confirmation'] = 0; - $this->getRequest()->setPostValue('order', $orderData); - - try { - //do not cancel old order. - $oldOrder = $this->_getOrderCreateModel()->getSession()->getOrder(); - $oldOrder->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_CANCEL, false); - - $order = $this->_getOrderCreateModel()->setIsValidate( - true - )->importPostData( - $this->getRequest()->getPost('order') - )->createOrder(); - - $payment = $order->getPayment(); - if ($payment && $payment->getMethod() == $this->_objectManager->create( - \Magento\Authorizenet\Model\Directpost::class - )->getCode() - ) { - //return json with data. - $session = $this->_objectManager->get(\Magento\Authorizenet\Model\Directpost\Session::class); - $session->addCheckoutOrderIncrementId($order->getIncrementId()); - $session->setLastOrderIncrementId($order->getIncrementId()); - - /** @var \Magento\Authorizenet\Model\Directpost $method */ - $method = $payment->getMethodInstance(); - $method->setDataHelper($this->helper); - $requestToAuthorizenet = $method->generateRequestFromOrder($order); - $requestToAuthorizenet->setControllerActionName($controller); - $requestToAuthorizenet->setOrderSendConfirmation($sendConfirmationFlag); - $requestToAuthorizenet->setStoreId($this->_getOrderCreateModel()->getQuote()->getStoreId()); - - $adminUrl = $this->_objectManager->get(\Magento\Backend\Model\UrlInterface::class); - if ($adminUrl->useSecretKey()) { - $requestToAuthorizenet->setKey( - $adminUrl->getSecretKey('adminhtml', 'authorizenet_directpost_payment', 'redirect') - ); - } - $result['directpost'] = ['fields' => $requestToAuthorizenet->getData()]; - } - - $result['success'] = 1; - $isError = false; - } catch (\Magento\Framework\Exception\LocalizedException $e) { - $message = $e->getMessage(); - if (!empty($message)) { - $this->messageManager->addErrorMessage($message); - } - $isError = true; - } catch (\Exception $e) { - $this->messageManager->addExceptionMessage($e, __('Order saving error: %1', $e->getMessage())); - $isError = true; - } - - if ($isError) { - $result['success'] = 0; - $result['error'] = 1; - $result['redirect'] = $this->_objectManager->get( - \Magento\Backend\Model\UrlInterface::class - )->getUrl( - 'sales/order_create/' - ); - } - - $this->getResponse()->representJson( - $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode($result) - ); - } else { - $result = ['error_messages' => __('Please choose a payment method.')]; - $this->getResponse()->representJson( - $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode($result) - ); - } - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php deleted file mode 100644 index 3d0d572bd6265..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php +++ /dev/null @@ -1,20 +0,0 @@ -_coreRegistry = $coreRegistry; - $this->resultLayoutFactory = $resultLayoutFactory; - $this->helper = $helper; - parent::__construct( - $context, - $productHelper, - $escaper, - $resultPageFactory, - $resultForwardFactory - ); - } - - /** - * Return quote - * - * @param bool $cancelOrder - * @param string $errorMsg - * @return void - */ - protected function _returnQuote($cancelOrder, $errorMsg) - { - $directpostSession = $this->_objectManager->get(\Magento\Authorizenet\Model\Directpost\Session::class); - $incrementId = $directpostSession->getLastOrderIncrementId(); - if ($incrementId && $directpostSession->isCheckoutOrderIncrementIdExist($incrementId)) { - /* @var $order \Magento\Sales\Model\Order */ - $order = $this->_objectManager->create(\Magento\Sales\Model\Order::class)->loadByIncrementId($incrementId); - if ($order->getId()) { - $directpostSession->removeCheckoutOrderIncrementId($order->getIncrementId()); - if ($cancelOrder && $order->getState() == \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT) { - $order->registerCancellation($errorMsg)->save(); - } - } - } - } - - /** - * Retrieve params and put javascript into iframe - * - * @return \Magento\Framework\View\Result\Layout - */ - public function execute() - { - $redirectParams = $this->getRequest()->getParams(); - $params = []; - if (!empty($redirectParams['success']) - && isset($redirectParams['x_invoice_num']) - && isset($redirectParams['controller_action_name']) - ) { - $params['redirect_parent'] = $this->helper->getSuccessOrderUrl($redirectParams); - $directpostSession = $this->_objectManager->get(\Magento\Authorizenet\Model\Directpost\Session::class); - $directpostSession->unsetData('quote_id'); - //cancel old order - $oldOrder = $this->_getOrderCreateModel()->getSession()->getOrder(); - if ($oldOrder->getId()) { - /* @var $order \Magento\Sales\Model\Order */ - $order = $this->_objectManager->create(\Magento\Sales\Model\Order::class) - ->loadByIncrementId($redirectParams['x_invoice_num']); - - if ($order->getId()) { - $oldOrder->cancel()->save(); - $order->save(); - $this->_getOrderCreateModel()->getSession()->unsOrderId(); - } - } - //clear sessions - $this->_getSession()->clearStorage(); - $directpostSession->removeCheckoutOrderIncrementId($redirectParams['x_invoice_num']); - $this->_objectManager->get(\Magento\Backend\Model\Session::class)->clearStorage(); - $this->messageManager->addSuccess(__('You created the order.')); - } - - if (!empty($redirectParams['error_msg'])) { - $cancelOrder = empty($redirectParams['x_invoice_num']); - $this->_returnQuote($cancelOrder, $redirectParams['error_msg']); - } - - $this->_coreRegistry->register(Iframe::REGISTRY_KEY, array_merge($params, $redirectParams)); - return $this->resultLayoutFactory->create(); - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php deleted file mode 100644 index 06a6403915ff1..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php +++ /dev/null @@ -1,20 +0,0 @@ -_objectManager->get(\Magento\Authorizenet\Model\Directpost\Session::class); - $incrementId = $directpostSession->getLastOrderIncrementId(); - if ($incrementId && $directpostSession->isCheckoutOrderIncrementIdExist($incrementId)) { - /* @var $order \Magento\Sales\Model\Order */ - $order = $this->_objectManager->create(\Magento\Sales\Model\Order::class)->loadByIncrementId($incrementId); - if ($order->getId()) { - $directpostSession->removeCheckoutOrderIncrementId($order->getIncrementId()); - } - } - } - - /** - * Return order quote by ajax - * - * @return void - */ - public function execute() - { - $this->_returnQuote(); - $this->getResponse()->representJson( - $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode(['success' => 1]) - ); - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php deleted file mode 100644 index cc93ce5daedeb..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php +++ /dev/null @@ -1,17 +0,0 @@ -_coreRegistry = $coreRegistry; - $this->dataFactory = $dataFactory; - parent::__construct($context); - } - - /** - * Get checkout model - * - * @return \Magento\Checkout\Model\Session - */ - protected function _getCheckout() - { - return $this->_objectManager->get(\Magento\Checkout\Model\Session::class); - } - - /** - * Get session model - * - * @return \Magento\Authorizenet\Model\Directpost\Session - */ - protected function _getDirectPostSession() - { - return $this->_objectManager->get(\Magento\Authorizenet\Model\Directpost\Session::class); - } - - /** - * Response action. - * - * Action for Authorize.net SIM Relay Request. - * - * @param string $area - * @return void - */ - protected function _responseAction($area = 'frontend') - { - $helper = $this->dataFactory->create($area); - - $params = []; - $data = $this->getRequest()->getParams(); - - /* @var $paymentMethod \Magento\Authorizenet\Model\DirectPost */ - $paymentMethod = $this->_objectManager->create(\Magento\Authorizenet\Model\Directpost::class); - - $result = []; - if (!empty($data['x_invoice_num'])) { - $result['x_invoice_num'] = $data['x_invoice_num']; - $params['order_success'] = $helper->getSuccessOrderUrl($result); - } - - try { - if (!empty($data['store_id'])) { - $paymentMethod->setStore($data['store_id']); - } - $paymentMethod->process($data); - $result['success'] = 1; - } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e); - $result['success'] = 0; - $result['error_msg'] = $e->getMessage(); - } catch (\Exception $e) { - $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e); - $result['success'] = 0; - $result['error_msg'] = __('We can\'t process your order right now. Please try again later.'); - } - - if (!empty($data['controller_action_name']) - && strpos($data['controller_action_name'], 'sales_order_') === false - ) { - if (!empty($data['key'])) { - $result['key'] = $data['key']; - } - $result['controller_action_name'] = $data['controller_action_name']; - $result['is_secure'] = isset($data['is_secure']) ? $data['is_secure'] : false; - $params['redirect'] = $helper->getRedirectIframeUrl($result); - } - - //registering parameter for iframe content - $this->_coreRegistry->register(Iframe::REGISTRY_KEY, $params); - } - - /** - * Return customer quote - * - * @param bool $cancelOrder - * @param string $errorMsg - * @return void - */ - protected function _returnCustomerQuote($cancelOrder = false, $errorMsg = '') - { - $incrementId = $this->_getDirectPostSession()->getLastOrderIncrementId(); - if ($incrementId && $this->_getDirectPostSession()->isCheckoutOrderIncrementIdExist($incrementId)) { - /* @var $order \Magento\Sales\Model\Order */ - $order = $this->_objectManager->create(\Magento\Sales\Model\Order::class)->loadByIncrementId($incrementId); - if ($order->getId()) { - try { - /** @var \Magento\Quote\Api\CartRepositoryInterface $quoteRepository */ - $quoteRepository = $this->_objectManager->create(\Magento\Quote\Api\CartRepositoryInterface::class); - /** @var \Magento\Quote\Model\Quote $quote */ - $quote = $quoteRepository->get($order->getQuoteId()); - - $quote->setIsActive(1)->setReservedOrderId(null); - $quoteRepository->save($quote); - $this->_getCheckout()->replaceQuote($quote); - } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { - } - $this->_getDirectPostSession()->removeCheckoutOrderIncrementId($incrementId); - $this->_getDirectPostSession()->unsetData('quote_id'); - if ($cancelOrder) { - $order->registerCancellation($errorMsg)->save(); - } - } - } - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php deleted file mode 100644 index e0610a92feb6a..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php +++ /dev/null @@ -1,107 +0,0 @@ -directpostFactory = $directpostFactory ?: $this->_objectManager->create(DirectpostFactory::class); - $this->logger = $logger ?: $this->_objectManager->get(LoggerInterface::class); - } - - /** - * @inheritDoc - */ - public function createCsrfValidationException( - RequestInterface $request - ): ?InvalidRequestException { - return null; - } - - /** - * @inheritDoc - */ - public function validateForCsrf(RequestInterface $request): ?bool - { - return true; - } - - /** - * Response action. - * - * Action for Authorize.net SIM Relay Request. - * - * @return \Magento\Framework\Controller\ResultInterface - */ - public function execute() - { - $data = $this->getRequest()->getParams(); - /** @var Directpost $paymentMethod */ - $paymentMethod = $this->directpostFactory->create(); - if (!empty($data['store_id'])) { - $paymentMethod->setStore($data['store_id']); - } - $paymentMethod->setResponseData($data); - try { - $paymentMethod->validateResponse(); - } catch (LocalizedException $e) { - $this->logger->critical($e->getMessage()); - return $this->_redirect('noroute'); - } - $this->_responseAction('adminhtml'); - return $this->resultFactory->create(ResultFactory::TYPE_PAGE); - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php deleted file mode 100644 index 7d672a75f5b17..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php +++ /dev/null @@ -1,161 +0,0 @@ -eventManager = $context->getEventManager(); - $this->cartManagement = $cartManagement; - $this->onepageCheckout = $onepageCheckout; - $this->jsonHelper = $jsonHelper; - $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class); - parent::__construct($context, $coreRegistry, $dataFactory); - } - - /** - * Send request to authorize.net - * - * @return string - */ - public function execute() - { - $paymentParam = $this->getRequest()->getParam('payment'); - $controller = $this->getRequest()->getParam('controller'); - $response = $this->getResponse(); - - if (isset($paymentParam['method'])) { - $this->_getDirectPostSession()->setQuoteId($this->_getCheckout()->getQuote()->getId()); - /** - * Current workaround depends on Onepage checkout model defect - * Method Onepage::getCheckoutMethod performs setCheckoutMethod - */ - $this->onepageCheckout->getCheckoutMethod(); - - if ($controller == IframeConfigProvider::CHECKOUT_IDENTIFIER) { - return $this->placeCheckoutOrder(); - } - - $params = $this->dataFactory - ->create(DataFactory::AREA_FRONTEND) - ->getSaveOrderUrlParams($controller); - $this->_forward( - $params['action'], - $params['controller'], - $params['module'], - $this->getRequest()->getParams() - ); - } else { - $result = ['error_messages' => __('Please choose a payment method.'), 'goto_section' => 'payment']; - if ($response instanceof Http) { - $response->representJson($this->jsonHelper->jsonEncode($result)); - } - } - } - - /** - * Place order for checkout flow - * - * @return void - */ - protected function placeCheckoutOrder() - { - $result = new DataObject(); - $response = $this->getResponse(); - try { - $this->cartManagement->placeOrder($this->_getCheckout()->getQuote()->getId()); - $result->setData('success', true); - $this->eventManager->dispatch( - 'checkout_directpost_placeOrder', - [ - 'result' => $result, - 'action' => $this - ] - ); - } catch (LocalizedException $exception) { - $this->logger->critical($exception); - $result->setData('error', true); - $result->setData('error_messages', $exception->getMessage()); - } catch (\Exception $exception) { - $this->logger->critical($exception); - $result->setData('error', true); - $result->setData( - 'error_messages', - __('A server error stopped your order from being placed. Please try to place your order again.') - ); - } - if ($response instanceof Http) { - $response->representJson($this->jsonHelper->jsonEncode($result)); - } - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php deleted file mode 100644 index 8c9510243f610..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php +++ /dev/null @@ -1,58 +0,0 @@ -dataFactory->create('frontend'); - - $redirectParams = $this->getRequest()->getParams(); - $params = []; - if (!empty($redirectParams['success']) - && isset($redirectParams['x_invoice_num']) - && isset($redirectParams['controller_action_name']) - ) { - $this->_getDirectPostSession()->unsetData('quote_id'); - $params['redirect_parent'] = $helper->getSuccessOrderUrl([]); - } - - if (!empty($redirectParams['error_msg'])) { - $cancelOrder = empty($redirectParams['x_invoice_num']); - $this->_returnCustomerQuote($cancelOrder, $redirectParams['error_msg']); - $params['error_msg'] = $redirectParams['error_msg']; - } - - if (isset($redirectParams['controller_action_name']) - && strpos($redirectParams['controller_action_name'], 'sales_order_') !== false - ) { - unset($redirectParams['controller_action_name']); - unset($params['redirect_parent']); - } - - $this->_coreRegistry->register(Iframe::REGISTRY_KEY, $params); - $this->_view->addPageLayoutHandles(); - $this->_view->loadLayout(false)->renderLayout(); - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php deleted file mode 100644 index 17fc3cb72e454..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php +++ /dev/null @@ -1,53 +0,0 @@ -_responseAction('frontend'); - return $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_PAGE); - } -} diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php deleted file mode 100644 index c974632f584b0..0000000000000 --- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php +++ /dev/null @@ -1,33 +0,0 @@ -_returnCustomerQuote(); - $this->getResponse()->representJson( - $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode(['success' => 1]) - ); - } -} diff --git a/app/code/Magento/Authorizenet/Helper/Backend/Data.php b/app/code/Magento/Authorizenet/Helper/Backend/Data.php deleted file mode 100644 index d291125ccae06..0000000000000 --- a/app/code/Magento/Authorizenet/Helper/Backend/Data.php +++ /dev/null @@ -1,109 +0,0 @@ -_urlBuilder = $backendUrl; - } - - /** - * Return URL for admin area - * - * @param string $route - * @param array $params - * @return string - */ - protected function _getUrl($route, $params = []) - { - return $this->_urlBuilder->getUrl($route, $params); - } - - /** - * Retrieve place order url in admin - * - * @return string - */ - public function getPlaceOrderAdminUrl() - { - return $this->_getUrl('adminhtml/authorizenet_directpost_payment/place', []); - } - - /** - * Retrieve place order url - * - * @param array $params - * @return string - */ - public function getSuccessOrderUrl($params) - { - $param = []; - $route = 'sales/order/view'; - $order = $this->orderFactory->create()->loadByIncrementId($params['x_invoice_num']); - $param['order_id'] = $order->getId(); - return $this->_getUrl($route, $param); - } - - /** - * Retrieve redirect iframe url - * - * @param array $params - * @return string - */ - public function getRedirectIframeUrl($params) - { - return $this->_getUrl('adminhtml/authorizenet_directpost_payment/redirect', $params); - } - - /** - * Get direct post relay url - * - * @param null|int|string $storeId - * @return string - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function getRelayUrl($storeId = null) - { - $defaultStore = $this->storeManager->getDefaultStoreView(); - if (!$defaultStore) { - $allStores = $this->storeManager->getStores(); - if (isset($allStores[0])) { - $defaultStore = $allStores[0]; - } - } - $baseUrl = $defaultStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK); - return $baseUrl . 'authorizenet/directpost_payment/backendResponse'; - } -} diff --git a/app/code/Magento/Authorizenet/Helper/Data.php b/app/code/Magento/Authorizenet/Helper/Data.php deleted file mode 100644 index e240cd692a13f..0000000000000 --- a/app/code/Magento/Authorizenet/Helper/Data.php +++ /dev/null @@ -1,344 +0,0 @@ - 'Authorized/Pending Capture', - 'capturedPendingSettlement' => 'Captured/Pending Settlement', - 'refundSettledSuccessfully' => 'Refund/Settled Successfully', - 'refundPendingSettlement' => 'Refund/Pending Settlement', - 'declined' => 'Declined', - 'expired' => 'Expired', - 'voided' => 'Voided', - 'FDSPendingReview' => 'FDS - Pending Review', - 'FDSAuthorizedPendingReview' => 'FDS - Authorized/Pending Review' - ]; - - /** - * Fraud filter actions key to value map - * - * @var array - */ - protected $fdsFilterActions = [ - 'decline ' => 'Decline', - 'hold' => 'Hold', - 'authAndHold' => 'Authorize and Hold', - 'report' => 'Report Only' - ]; - - /** - * @param \Magento\Framework\App\Helper\Context $context - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Sales\Model\OrderFactory $orderFactory - */ - public function __construct( - Context $context, - StoreManagerInterface $storeManager, - OrderFactory $orderFactory - ) { - $this->storeManager = $storeManager; - $this->orderFactory = $orderFactory; - parent::__construct($context); - } - - /** - * Set secure url checkout is secure for current store. - * - * @param string $route - * @param array $params - * @return string - */ - protected function _getUrl($route, $params = []) - { - $params['_type'] = \Magento\Framework\UrlInterface::URL_TYPE_LINK; - if (isset($params['is_secure'])) { - $params['_secure'] = (bool)$params['is_secure']; - } elseif ($this->storeManager->getStore()->isCurrentlySecure()) { - $params['_secure'] = true; - } - return parent::_getUrl($route, $params); - } - - /** - * Retrieve save order url params - * - * @param string $controller - * @return array - */ - public function getSaveOrderUrlParams($controller) - { - $route = []; - switch ($controller) { - case 'onepage': - $route['action'] = 'saveOrder'; - $route['controller'] = 'onepage'; - $route['module'] = 'checkout'; - break; - - case 'sales_order_create': - case 'sales_order_edit': - $route['action'] = 'save'; - $route['controller'] = 'sales_order_create'; - $route['module'] = 'admin'; - break; - - default: - break; - } - - return $route; - } - - /** - * Retrieve redirect iframe url - * - * @param array $params - * @return string - */ - public function getRedirectIframeUrl($params) - { - return $this->_getUrl('authorizenet/directpost_payment/redirect', $params); - } - - /** - * Retrieve place order url - * - * @param array $params - * @return string - */ - public function getSuccessOrderUrl($params) - { - return $this->_getUrl('checkout/onepage/success', $params); - } - - /** - * Update all child and parent order's edit increment numbers. - * - * Needed for Admin area. - * - * @param \Magento\Sales\Model\Order $order - * @return void - */ - public function updateOrderEditIncrements(\Magento\Sales\Model\Order $order) - { - if ($order->getId() && $order->getOriginalIncrementId()) { - $collection = $order->getCollection(); - $quotedIncrId = $collection->getConnection()->quote($order->getOriginalIncrementId()); - $collection->getSelect()->where( - "original_increment_id = {$quotedIncrId} OR increment_id = {$quotedIncrId}" - ); - - foreach ($collection as $orderToUpdate) { - $orderToUpdate->setEditIncrement($order->getEditIncrement()); - $orderToUpdate->save(); - } - } - } - - /** - * Converts a lot of messages to message - * - * @param array $messages - * @return string - */ - public function convertMessagesToMessage($messages) - { - return implode(' | ', $messages); - } - - /** - * Return message for gateway transaction request - * - * @param \Magento\Payment\Model\InfoInterface $payment - * @param string $requestType - * @param string $lastTransactionId - * @param \Magento\Framework\DataObject $card - * @param bool|float $amount - * @param bool|string $exception - * @param bool|string $additionalMessage - * @return bool|string - */ - public function getTransactionMessage( - $payment, - $requestType, - $lastTransactionId, - $card, - $amount = false, - $exception = false, - $additionalMessage = false - ) { - $message[] = __('Credit Card: xxxx-%1', $card->getCcLast4()); - if ($amount) { - $message[] = __('amount %1', $this->formatPrice($payment, $amount)); - } - $operation = $this->getOperation($requestType); - if (!$operation) { - return false; - } else { - $message[] = $operation; - } - $message[] = ($exception) ? '- ' . __('failed.') : '- ' . __('successful.'); - if ($lastTransactionId !== null) { - $message[] = __('Authorize.Net Transaction ID %1.', $lastTransactionId); - } - if ($additionalMessage) { - $message[] = $additionalMessage; - } - if ($exception) { - $message[] = $exception; - } - return implode(' ', $message); - } - - /** - * Return operation name for request type - * - * @param string $requestType - * @return \Magento\Framework\Phrase|bool - */ - protected function getOperation($requestType) - { - switch ($requestType) { - case Authorizenet::REQUEST_TYPE_AUTH_ONLY: - return __('authorize'); - case Authorizenet::REQUEST_TYPE_AUTH_CAPTURE: - return __('authorize and capture'); - case Authorizenet::REQUEST_TYPE_PRIOR_AUTH_CAPTURE: - return __('capture'); - case Authorizenet::REQUEST_TYPE_CREDIT: - return __('refund'); - case Authorizenet::REQUEST_TYPE_VOID: - return __('void'); - default: - return false; - } - } - - /** - * Format price with currency sign - * - * @param \Magento\Payment\Model\InfoInterface $payment - * @param float $amount - * @return string - */ - protected function formatPrice($payment, $amount) - { - return $payment->getOrder()->getBaseCurrency()->formatTxt($amount); - } - - /** - * Get payment method step html - * - * @param \Magento\Framework\App\ViewInterface $view - * @return string - */ - public function getPaymentMethodsHtml(\Magento\Framework\App\ViewInterface $view) - { - $layout = $view->getLayout(); - $update = $layout->getUpdate(); - $update->load('checkout_onepage_paymentmethod'); - $layout->generateXml(); - $layout->generateElements(); - $output = $layout->getOutput(); - return $output; - } - - /** - * Get direct post relay url - * - * @param null|int|string $storeId - * @return string - */ - public function getRelayUrl($storeId = null) - { - $baseUrl = $this->storeManager->getStore($storeId) - ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK); - return $baseUrl . 'authorizenet/directpost_payment/response'; - } - - /** - * Get allowed currencies - * - * @return array - */ - public function getAllowedCurrencyCodes() - { - return $this->allowedCurrencyCodes; - } - - /** - * Get translated filter action label - * - * @param string $key - * @return \Magento\Framework\Phrase|string - */ - public function getFdsFilterActionLabel($key) - { - return isset($this->fdsFilterActions[$key]) ? __($this->fdsFilterActions[$key]) : $key; - } - - /** - * Get translated transaction status label - * - * @param string $key - * @return \Magento\Framework\Phrase|string - */ - public function getTransactionStatusLabel($key) - { - return isset($this->transactionStatuses[$key]) ? __($this->transactionStatuses[$key]) : $key; - } - - /** - * Gateway error response wrapper - * - * @param string $text - * @return \Magento\Framework\Phrase - */ - public function wrapGatewayError($text) - { - return __('Gateway error: %1', $text); - } -} diff --git a/app/code/Magento/Authorizenet/Helper/DataFactory.php b/app/code/Magento/Authorizenet/Helper/DataFactory.php deleted file mode 100644 index 71f16ab4af646..0000000000000 --- a/app/code/Magento/Authorizenet/Helper/DataFactory.php +++ /dev/null @@ -1,60 +0,0 @@ - \Magento\Authorizenet\Helper\Data::class, - self::AREA_BACKEND => \Magento\Authorizenet\Helper\Backend\Data::class - ]; - - /** - * Constructor - * - * @param ObjectManagerInterface $objectManager - */ - public function __construct(ObjectManagerInterface $objectManager) - { - $this->objectManager = $objectManager; - } - - /** - * Create data helper - * - * @param string $area - * @return \Magento\Authorizenet\Helper\Backend\Data|\Magento\Authorizenet\Helper\Data - * @throws LocalizedException - */ - public function create($area) - { - if (!isset($this->helperMap[$area])) { - throw new LocalizedException(__(sprintf('For this area <%s> no suitable helper', $area))); - } - - return $this->objectManager->get($this->helperMap[$area]); - } -} diff --git a/app/code/Magento/Authorizenet/Model/Authorizenet.php b/app/code/Magento/Authorizenet/Model/Authorizenet.php deleted file mode 100644 index 9370b649a23c7..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Authorizenet.php +++ /dev/null @@ -1,449 +0,0 @@ -dataHelper = $dataHelper; - $this->requestFactory = $requestFactory; - $this->responseFactory = $responseFactory; - $this->transactionService = $transactionService; - $this->httpClientFactory = $httpClientFactory; - - parent::__construct( - $context, - $registry, - $extensionFactory, - $customAttributeFactory, - $paymentData, - $scopeConfig, - $logger, - $moduleList, - $localeDate, - $resource, - $resourceCollection, - $data - ); - } - - /** - * Check method for processing with base currency - * - * @param string $currencyCode - * @return bool - */ - public function canUseForCurrency($currencyCode) - { - if (!in_array($currencyCode, $this->getAcceptedCurrencyCodes())) { - return false; - } - return true; - } - - /** - * Return array of currency codes supplied by Payment Gateway - * - * @return array - */ - public function getAcceptedCurrencyCodes() - { - if (!$this->hasData('_accepted_currency')) { - $acceptedCurrencyCodes = $this->dataHelper->getAllowedCurrencyCodes(); - $acceptedCurrencyCodes[] = $this->getConfigData('currency'); - $this->setData('_accepted_currency', $acceptedCurrencyCodes); - } - return $this->_getData('_accepted_currency'); - } - - /** - * Cancel the payment through gateway - * - * @param \Magento\Payment\Model\InfoInterface $payment - * @return $this - */ - public function cancel(\Magento\Payment\Model\InfoInterface $payment) - { - return $this->void($payment); - } - - /** - * Fetch fraud details - * - * @param string $transactionId - * @return \Magento\Framework\DataObject - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function fetchTransactionFraudDetails($transactionId) - { - $responseXmlDocument = $this->transactionService->getTransactionDetails($this, $transactionId); - $response = new \Magento\Framework\DataObject(); - - if (empty($responseXmlDocument->transaction->FDSFilters->FDSFilter)) { - return $response; - } - - $response->setFdsFilterAction( - $this->dataHelper->getFdsFilterActionLabel((string)$responseXmlDocument->transaction->FDSFilterAction) - ); - $response->setAvsResponse((string)$responseXmlDocument->transaction->AVSResponse); - $response->setCardCodeResponse((string)$responseXmlDocument->transaction->cardCodeResponse); - $response->setCavvResponse((string)$responseXmlDocument->transaction->CAVVResponse); - $response->setFraudFilters($this->getFraudFilters($responseXmlDocument->transaction->FDSFilters)); - - return $response; - } - - /** - * Get fraud filters - * - * @param \Magento\Framework\Simplexml\Element $fraudFilters - * @return array - */ - protected function getFraudFilters($fraudFilters) - { - $result = []; - - foreach ($fraudFilters->FDSFilter as $filer) { - $result[] = [ - 'name' => (string)$filer->name, - 'action' => $this->dataHelper->getFdsFilterActionLabel((string)$filer->action) - ]; - } - - return $result; - } - - /** - * Return authorize payment request - * - * @return \Magento\Authorizenet\Model\Request - */ - protected function getRequest() - { - $request = $this->requestFactory->create() - ->setXVersion(3.1) - ->setXDelimData('True') - ->setXRelayResponse('False') - ->setXTestRequest($this->getConfigData('test') ? 'TRUE' : 'FALSE') - ->setXLogin($this->getConfigData('login')) - ->setXTranKey($this->getConfigData('trans_key')); - return $request; - } - - /** - * Prepare request to gateway - * - * @param \Magento\Framework\DataObject|\Magento\Payment\Model\InfoInterface $payment - * @return \Magento\Authorizenet\Model\Request - * @link http://www.authorize.net/support/AIM_guide.pdf - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - protected function buildRequest(\Magento\Framework\DataObject $payment) - { - /** @var \Magento\Sales\Model\Order $order */ - $order = $payment->getOrder(); - $this->setStore($order->getStoreId()); - $request = $this->getRequest() - ->setXType($payment->getAnetTransType()) - ->setXMethod(self::REQUEST_METHOD_CC); - - if ($order && $order->getIncrementId()) { - $request->setXInvoiceNum($order->getIncrementId()); - } - - if ($payment->getAmount()) { - $request->setXAmount($payment->getAmount(), 2); - $request->setXCurrencyCode($order->getBaseCurrencyCode()); - } - - switch ($payment->getAnetTransType()) { - case self::REQUEST_TYPE_AUTH_CAPTURE: - $request->setXAllowPartialAuth($this->getConfigData('allow_partial_authorization') ? 'True' : 'False'); - break; - case self::REQUEST_TYPE_AUTH_ONLY: - $request->setXAllowPartialAuth($this->getConfigData('allow_partial_authorization') ? 'True' : 'False'); - break; - case self::REQUEST_TYPE_CREDIT: - /** - * Send last 4 digits of credit card number to authorize.net - * otherwise it will give an error - */ - $request->setXCardNum($payment->getCcLast4()); - $request->setXTransId($payment->getXTransId()); - break; - case self::REQUEST_TYPE_VOID: - $request->setXTransId($payment->getXTransId()); - break; - case self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE: - $request->setXTransId($payment->getXTransId()); - break; - case self::REQUEST_TYPE_CAPTURE_ONLY: - $request->setXAuthCode($payment->getCcAuthCode()); - break; - } - - if (!empty($order)) { - $billing = $order->getBillingAddress(); - if (!empty($billing)) { - $request->setXFirstName($billing->getFirstname()) - ->setXLastName($billing->getLastname()) - ->setXCompany($billing->getCompany()) - ->setXAddress($billing->getStreetLine(1)) - ->setXCity($billing->getCity()) - ->setXState($billing->getRegion()) - ->setXZip($billing->getPostcode()) - ->setXCountry($billing->getCountryId()) - ->setXPhone($billing->getTelephone()) - ->setXFax($billing->getFax()) - ->setXCustId($order->getCustomerId()) - ->setXCustomerIp($order->getRemoteIp()) - ->setXCustomerTaxId($billing->getTaxId()) - ->setXEmail($order->getCustomerEmail()) - ->setXEmailCustomer($this->getConfigData('email_customer')) - ->setXMerchantEmail($this->getConfigData('merchant_email')); - } - - $shipping = $order->getShippingAddress(); - if (!empty($shipping)) { - $request->setXShipToFirstName($shipping->getFirstname()) - ->setXShipToLastName($shipping->getLastname()) - ->setXShipToCompany($shipping->getCompany()) - ->setXShipToAddress($shipping->getStreetLine(1)) - ->setXShipToCity($shipping->getCity()) - ->setXShipToState($shipping->getRegion()) - ->setXShipToZip($shipping->getPostcode()) - ->setXShipToCountry($shipping->getCountryId()); - } - - $request->setXPoNum($payment->getPoNumber()) - ->setXTax($order->getBaseTaxAmount()) - ->setXFreight($order->getBaseShippingAmount()); - } - - if ($payment->getCcNumber()) { - $request->setXCardNum($payment->getCcNumber()) - ->setXExpDate(sprintf('%02d-%04d', $payment->getCcExpMonth(), $payment->getCcExpYear())) - ->setXCardCode($payment->getCcCid()); - } - - return $request; - } - - /** - * Post request to gateway and return response - * - * @param \Magento\Authorizenet\Model\Request $request - * @return \Magento\Authorizenet\Model\Response - * @throws \Magento\Framework\Exception\LocalizedException - */ - protected function postRequest(\Magento\Authorizenet\Model\Request $request) - { - $result = $this->responseFactory->create(); - /** @var \Magento\Framework\HTTP\ZendClient $client */ - $client = $this->httpClientFactory->create(); - $url = $this->getConfigData('cgi_url') ?: self::CGI_URL; - $debugData = ['url' => $url, 'request' => $request->getData()]; - $client->setUri($url); - $client->setConfig(['maxredirects' => 0, 'timeout' => 30]); - - foreach ($request->getData() as $key => $value) { - $request->setData($key, str_replace(self::RESPONSE_DELIM_CHAR, '', $value)); - } - - $request->setXDelimChar(self::RESPONSE_DELIM_CHAR); - $client->setParameterPost($request->getData()); - $client->setMethod(\Zend_Http_Client::POST); - - try { - $response = $client->request(); - $responseBody = $response->getBody(); - $debugData['response'] = $responseBody; - } catch (\Exception $e) { - $result->setXResponseCode(-1) - ->setXResponseReasonCode($e->getCode()) - ->setXResponseReasonText($e->getMessage()); - - throw new \Magento\Framework\Exception\LocalizedException( - $this->dataHelper->wrapGatewayError($e->getMessage()) - ); - } finally { - $this->_debug($debugData); - } - - $r = explode(self::RESPONSE_DELIM_CHAR, $responseBody); - if ($r) { - $result->setXResponseCode((int)str_replace('"', '', $r[0])) - ->setXResponseReasonCode((int)str_replace('"', '', $r[2])) - ->setXResponseReasonText($r[3]) - ->setXAvsCode($r[5]) - ->setXTransId($r[6]) - ->setXInvoiceNum($r[7]) - ->setXAmount($r[9]) - ->setXMethod($r[10]) - ->setXType($r[11]) - ->setData('x_MD5_Hash', $r[37]) - ->setXAccountNumber($r[50]); - } else { - throw new \Magento\Framework\Exception\LocalizedException( - __('Something went wrong in the payment gateway.') - ); - } - return $result; - } - - /** - * If gateway actions are locked return true - * - * @param \Magento\Payment\Model\InfoInterface $payment - * @return bool - */ - protected function isGatewayActionsLocked($payment) - { - return $payment->getAdditionalInformation(self::GATEWAY_ACTIONS_LOCKED_STATE_KEY); - } -} diff --git a/app/code/Magento/Authorizenet/Model/Debug.php b/app/code/Magento/Authorizenet/Model/Debug.php deleted file mode 100644 index 93d508cc744e1..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Debug.php +++ /dev/null @@ -1,38 +0,0 @@ -_init(\Magento\Authorizenet\Model\ResourceModel\Debug::class); - } -} diff --git a/app/code/Magento/Authorizenet/Model/Directpost.php b/app/code/Magento/Authorizenet/Model/Directpost.php deleted file mode 100644 index 946ec8ba01a0e..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Directpost.php +++ /dev/null @@ -1,1070 +0,0 @@ -orderFactory = $orderFactory; - $this->storeManager = $storeManager; - $this->quoteRepository = $quoteRepository; - $this->response = $responseFactory->create(); - $this->orderSender = $orderSender; - $this->transactionRepository = $transactionRepository; - $this->_code = static::METHOD_CODE; - $this->paymentFailures = $paymentFailures ? : ObjectManager::getInstance() - ->get(\Magento\Sales\Api\PaymentFailuresInterface::class); - - parent::__construct( - $context, - $registry, - $extensionFactory, - $customAttributeFactory, - $paymentData, - $scopeConfig, - $logger, - $moduleList, - $localeDate, - $dataHelper, - $requestFactory, - $responseFactory, - $transactionService, - $httpClientFactory, - $resource, - $resourceCollection, - $data - ); - } - - /** - * Set data helper - * - * @param \Magento\Authorizenet\Helper\Data $dataHelper - * @return void - */ - public function setDataHelper(\Magento\Authorizenet\Helper\Data $dataHelper) - { - $this->dataHelper = $dataHelper; - } - - /** - * Do not validate payment form using server methods - * - * @return bool - */ - public function validate() - { - return true; - } - - /** - * Send authorize request to gateway - * - * @param \Magento\Framework\DataObject|\Magento\Payment\Model\InfoInterface $payment - * @param float $amount - * @return void - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function authorize(\Magento\Payment\Model\InfoInterface $payment, $amount) - { - $payment->setAdditionalInformation('payment_type', $this->getConfigData('payment_action')); - } - - /** - * Send capture request to gateway - * - * @param \Magento\Framework\DataObject|\Magento\Payment\Model\InfoInterface $payment - * @param float $amount - * @return $this - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount) - { - if ($amount <= 0) { - throw new \Magento\Framework\Exception\LocalizedException(__('Invalid amount for capture.')); - } - - $payment->setAmount($amount); - - if ($payment->getParentTransactionId()) { - $payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE); - $payment->setXTransId($this->getRealParentTransactionId($payment)); - } else { - $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_CAPTURE); - } - - $result = $this->getResponse(); - if (empty($result->getData())) { - $request = $this->buildRequest($payment); - $result = $this->postRequest($request); - } - - return $this->processCapture($result, $payment); - } - - /** - * Process capture request - * - * @param \Magento\Authorizenet\Model\Directpost\Response $result - * @param \Magento\Payment\Model\InfoInterface $payment - * @return $this - * @throws \Magento\Framework\Exception\LocalizedException - */ - protected function processCapture($result, $payment) - { - switch ($result->getXResponseCode()) { - case self::RESPONSE_CODE_APPROVED: - case self::RESPONSE_CODE_HELD: - if (in_array( - $result->getXResponseReasonCode(), - [ - self::RESPONSE_REASON_CODE_APPROVED, - self::RESPONSE_REASON_CODE_PENDING_REVIEW, - self::RESPONSE_REASON_CODE_PENDING_REVIEW_AUTHORIZED - ] - ) - ) { - if (!$payment->getParentTransactionId() - || $result->getXTransId() != $payment->getParentTransactionId() - ) { - $payment->setTransactionId($result->getXTransId()); - } - $payment->setIsTransactionClosed(0) - ->setTransactionAdditionalInfo( - self::REAL_TRANSACTION_ID_KEY, - $result->getXTransId() - ); - return $this; - } - throw new \Magento\Framework\Exception\LocalizedException( - $this->dataHelper->wrapGatewayError($result->getXResponseReasonText()) - ); - case self::RESPONSE_CODE_DECLINED: - case self::RESPONSE_CODE_ERROR: - throw new \Magento\Framework\Exception\LocalizedException( - $this->dataHelper->wrapGatewayError($result->getXResponseReasonText()) - ); - default: - throw new \Magento\Framework\Exception\LocalizedException(__('Payment capturing error.')); - } - } - - /** - * Void the payment through gateway - * - * @param \Magento\Framework\DataObject|\Magento\Payment\Model\InfoInterface $payment - * @return $this - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function void(\Magento\Payment\Model\InfoInterface $payment) - { - if (!$payment->getParentTransactionId()) { - throw new \Magento\Framework\Exception\LocalizedException(__('Invalid transaction ID.')); - } - - $payment->setAnetTransType(self::REQUEST_TYPE_VOID); - $payment->setXTransId($this->getRealParentTransactionId($payment)); - - $request = $this->buildRequest($payment); - $result = $this->postRequest($request); - - switch ($result->getXResponseCode()) { - case self::RESPONSE_CODE_APPROVED: - if ($result->getXResponseReasonCode() == self::RESPONSE_REASON_CODE_APPROVED) { - if ($result->getXTransId() != $payment->getParentTransactionId()) { - $payment->setTransactionId($result->getXTransId()); - } - $payment->setIsTransactionClosed(1) - ->setShouldCloseParentTransaction(1) - ->setTransactionAdditionalInfo(self::REAL_TRANSACTION_ID_KEY, $result->getXTransId()); - return $this; - } - throw new \Magento\Framework\Exception\LocalizedException( - $this->dataHelper->wrapGatewayError($result->getXResponseReasonText()) - ); - case self::RESPONSE_CODE_DECLINED: - case self::RESPONSE_CODE_ERROR: - throw new \Magento\Framework\Exception\LocalizedException( - $this->dataHelper->wrapGatewayError($result->getXResponseReasonText()) - ); - default: - throw new \Magento\Framework\Exception\LocalizedException(__('Payment voiding error.')); - } - } - - /** - * Refund the amount need to decode last 4 digits for request. - * - * @param \Magento\Framework\DataObject|\Magento\Payment\Model\InfoInterface $payment - * @param float $amount - * @return $this - * @throws \Exception - */ - public function refund(\Magento\Payment\Model\InfoInterface $payment, $amount) - { - $last4 = $payment->getCcLast4(); - $payment->setCcLast4($payment->decrypt($last4)); - try { - $this->processRefund($payment, $amount); - } catch (\Exception $e) { - $payment->setCcLast4($last4); - throw $e; - } - $payment->setCcLast4($last4); - return $this; - } - - /** - * Refund the amount with transaction id - * - * @param \Magento\Framework\DataObject $payment - * @param float $amount - * @return $this - * @throws \Magento\Framework\Exception\LocalizedException - */ - protected function processRefund(\Magento\Framework\DataObject $payment, $amount) - { - if ($amount <= 0) { - throw new \Magento\Framework\Exception\LocalizedException(__('Invalid amount for refund.')); - } - - if (!$payment->getParentTransactionId()) { - throw new \Magento\Framework\Exception\LocalizedException(__('Invalid transaction ID.')); - } - - $payment->setAnetTransType(self::REQUEST_TYPE_CREDIT); - $payment->setAmount($amount); - $payment->setXTransId($this->getRealParentTransactionId($payment)); - - $request = $this->buildRequest($payment); - $result = $this->postRequest($request); - - switch ($result->getXResponseCode()) { - case self::RESPONSE_CODE_APPROVED: - if ($result->getXResponseReasonCode() == self::RESPONSE_REASON_CODE_APPROVED) { - if ($result->getXTransId() != $payment->getParentTransactionId()) { - $payment->setTransactionId($result->getXTransId()); - } - $payment->setIsTransactionClosed(true) - ->setTransactionAdditionalInfo(self::REAL_TRANSACTION_ID_KEY, $result->getXTransId()); - return $this; - } - throw new \Magento\Framework\Exception\LocalizedException( - $this->dataHelper->wrapGatewayError($result->getXResponseReasonText()) - ); - case self::RESPONSE_CODE_DECLINED: - case self::RESPONSE_CODE_ERROR: - throw new \Magento\Framework\Exception\LocalizedException( - $this->dataHelper->wrapGatewayError($result->getXResponseReasonText()) - ); - default: - throw new \Magento\Framework\Exception\LocalizedException(__('Payment refunding error.')); - } - } - - /** - * Get CGI url - * - * @return string - */ - public function getCgiUrl() - { - $uri = $this->getConfigData('cgi_url'); - return $uri ? $uri : self::CGI_URL; - } - - /** - * Return URL on which Authorize.net server will return payment result data in hidden request. - * - * @param int $storeId - * @return string - */ - public function getRelayUrl($storeId = null) - { - if ($storeId == null && $this->getStore()) { - $storeId = $this->getStore(); - } - return $this->dataHelper->getRelayUrl($storeId); - } - - /** - * Return response. - * - * @return \Magento\Authorizenet\Model\Directpost\Response - */ - public function getResponse() - { - return $this->response; - } - - /** - * Instantiate state and set it to state object - * - * @param string $paymentAction - * @param \Magento\Framework\DataObject $stateObject - * @return void - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function initialize($paymentAction, $stateObject) - { - $requestType = null; - switch ($paymentAction) { - case self::ACTION_AUTHORIZE: - $requestType = self::REQUEST_TYPE_AUTH_ONLY; - //intentional - case self::ACTION_AUTHORIZE_CAPTURE: - $requestType = $requestType ?: self::REQUEST_TYPE_AUTH_CAPTURE; - $payment = $this->getInfoInstance(); - $order = $payment->getOrder(); - $order->setCanSendNewEmailFlag(false); - $payment->setBaseAmountAuthorized($order->getBaseTotalDue()); - $payment->setAmountAuthorized($order->getTotalDue()); - $payment->setAnetTransType($requestType); - break; - default: - break; - } - } - - /** - * Generate request object and fill its fields from Quote or Order object - * - * @param \Magento\Sales\Model\Order $order Quote or order object. - * @return \Magento\Authorizenet\Model\Directpost\Request - */ - public function generateRequestFromOrder(\Magento\Sales\Model\Order $order) - { - $request = $this->requestFactory->create() - ->setConstantData($this) - ->setDataFromOrder($order, $this) - ->signRequestData(); - - $this->_debug(['request' => $request->getData()]); - - return $request; - } - - /** - * Fill response with data. - * - * @param array $postData - * @return $this - */ - public function setResponseData(array $postData) - { - $this->getResponse()->setData($postData); - return $this; - } - - /** - * Validate response data. Needed in controllers. - * - * @return bool true in case of validation success. - * @throws \Magento\Framework\Exception\LocalizedException In case of validation error - */ - public function validateResponse() - { - $response = $this->getResponse(); - $hashConfigKey = !empty($response->getData('x_SHA2_Hash')) ? 'signature_key' : 'trans_md5'; - - //hash check - if (!$response->isValidHash($this->getConfigData($hashConfigKey), $this->getConfigData('login')) - ) { - throw new \Magento\Framework\Exception\LocalizedException( - __('The transaction was declined because the response hash validation failed.') - ); - } - - return true; - } - - /** - * Operate with order using data from $_POST which came from authorize.net by Relay URL. - * - * @param array $responseData data from Authorize.net from $_POST - * @return void - * @throws \Magento\Framework\Exception\LocalizedException In case of validation error or order creation error - */ - public function process(array $responseData) - { - $this->_debug(['response' => $responseData]); - - $this->setResponseData($responseData); - - //check MD5 error or others response errors - //throws exception on false. - $this->validateResponse(); - - $response = $this->getResponse(); - $responseText = $this->dataHelper->wrapGatewayError($response->getXResponseReasonText()); - $isError = false; - if ($this->getOrderIncrementId()) { - $order = $this->getOrderFromResponse(); - //check payment method - $payment = $order->getPayment(); - if (!$payment || $payment->getMethod() != $this->getCode()) { - throw new \Magento\Framework\Exception\LocalizedException( - __('This payment didn\'t work out because we can\'t find this order.') - ); - } - if ($order->getId()) { - //operate with order - $this->processOrder($order); - } else { - $isError = true; - } - } else { - $isError = true; - } - - if ($isError) { - $responseText = $responseText && !$response->isApproved() - ? $responseText - : __('This payment didn\'t work out because we can\'t find this order.'); - throw new \Magento\Framework\Exception\LocalizedException($responseText); - } - } - - /** - * Fill payment with credit card data from response from Authorize.net. - * - * @param \Magento\Framework\DataObject $payment - * @return void - */ - protected function fillPaymentByResponse(\Magento\Framework\DataObject $payment) - { - $response = $this->getResponse(); - $payment->setTransactionId($response->getXTransId()) - ->setParentTransactionId(null) - ->setIsTransactionClosed(0) - ->setTransactionAdditionalInfo(self::REAL_TRANSACTION_ID_KEY, $response->getXTransId()); - - if ($response->getXMethod() == self::REQUEST_METHOD_CC) { - $payment->setCcAvsStatus($response->getXAvsCode()) - ->setCcLast4($payment->encrypt(substr($response->getXAccountNumber(), -4))); - } - - if ($response->getXResponseCode() == self::RESPONSE_CODE_HELD) { - $payment->setIsTransactionPending(true) - ->setIsFraudDetected(true); - } - - $additionalInformationKeys = explode(',', $this->getValue('paymentInfoKeys')); - foreach ($additionalInformationKeys as $paymentInfoKey) { - $paymentInfoValue = $response->getDataByKey($paymentInfoKey); - if ($paymentInfoValue !== null) { - $payment->setAdditionalInformation($paymentInfoKey, $paymentInfoValue); - } - } - } - - /** - * Check response code came from Authorize.net. - * - * @return true in case of Approved response - * @throws \Magento\Framework\Exception\LocalizedException In case of Declined or Error response from Authorize.net - */ - public function checkResponseCode() - { - switch ($this->getResponse()->getXResponseCode()) { - case self::RESPONSE_CODE_APPROVED: - case self::RESPONSE_CODE_HELD: - return true; - case self::RESPONSE_CODE_DECLINED: - case self::RESPONSE_CODE_ERROR: - $errorMessage = $this->dataHelper->wrapGatewayError($this->getResponse()->getXResponseReasonText()); - $order = $this->getOrderFromResponse(); - $this->paymentFailures->handle((int)$order->getQuoteId(), (string)$errorMessage); - throw new \Magento\Framework\Exception\LocalizedException($errorMessage); - default: - throw new \Magento\Framework\Exception\LocalizedException( - __('There was a payment authorization error.') - ); - } - } - - /** - * Check transaction id came from Authorize.net - * - * @return true in case of right transaction id - * @throws \Magento\Framework\Exception\LocalizedException In case of bad transaction id. - */ - public function checkTransId() - { - if (!$this->getResponse()->getXTransId()) { - throw new \Magento\Framework\Exception\LocalizedException( - __('Please enter a transaction ID to authorize this payment.') - ); - } - return true; - } - - /** - * Compare amount with amount from the response from Authorize.net. - * - * @param float $amount - * @return bool - */ - protected function matchAmount($amount) - { - return sprintf('%.2F', $amount) == sprintf('%.2F', $this->getResponse()->getXAmount()); - } - - /** - * Operate with order using information from Authorize.net. - * - * Authorize order or authorize and capture it. - * - * @param \Magento\Sales\Model\Order $order - * @return void - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Exception - * @SuppressWarnings(PHPMD.NPathComplexity) - */ - protected function processOrder(\Magento\Sales\Model\Order $order) - { - try { - $this->checkResponseCode(); - $this->checkTransId(); - } catch (\Exception $e) { - //decline the order (in case of wrong response code) but don't return money to customer. - $message = $e->getMessage(); - $this->declineOrder($order, $message, false); - - throw $e; - } - - $response = $this->getResponse(); - - //create transaction. need for void if amount will not match. - $payment = $order->getPayment(); - $this->fillPaymentByResponse($payment); - $payment->getMethodInstance()->setIsInitializeNeeded(false); - $payment->getMethodInstance()->setResponseData($response->getData()); - $this->processPaymentFraudStatus($payment); - $payment->place(); - $this->addStatusComment($payment); - $order->save(); - - //match amounts. should be equals for authorization. - //decline the order if amount does not match. - if (!$this->matchAmount($payment->getBaseAmountAuthorized())) { - $message = __( - 'Something went wrong: the paid amount doesn\'t match the order amount.' - . ' Please correct this and try again.' - ); - $this->declineOrder($order, $message, true); - throw new \Magento\Framework\Exception\LocalizedException($message); - } - - try { - if (!$response->hasOrderSendConfirmation() || $response->getOrderSendConfirmation()) { - $this->orderSender->send($order); - } - - $quote = $this->quoteRepository->get($order->getQuoteId())->setIsActive(false); - $this->quoteRepository->save($quote); - } catch (\Exception $e) { - // do not cancel order if we couldn't send email - } - } - - /** - * Process fraud status - * - * @param \Magento\Sales\Model\Order\Payment $payment - * @return $this - */ - protected function processPaymentFraudStatus(\Magento\Sales\Model\Order\Payment $payment) - { - try { - $fraudDetailsResponse = $payment->getMethodInstance() - ->fetchTransactionFraudDetails($this->getResponse()->getXTransId()); - $fraudData = $fraudDetailsResponse->getData(); - - if (empty($fraudData)) { - $payment->setIsFraudDetected(false); - return $this; - } - - $fdsFilterAction = (string)$fraudDetailsResponse->getFdsFilterAction(); - if ($this->fdsFilterActionIsReportOnly($fdsFilterAction) === false) { - $payment->setIsFraudDetected(true); - } - - $payment->setAdditionalInformation('fraud_details', $fraudData); - } catch (\Exception $e) { - //this request is optional - } - - return $this; - } - - /** - * Add status comment to history - * - * @param \Magento\Sales\Model\Order\Payment $payment - * @return $this - */ - protected function addStatusComment(\Magento\Sales\Model\Order\Payment $payment) - { - try { - $transactionId = $this->getResponse()->getXTransId(); - $data = $this->transactionService->getTransactionDetails($this, $transactionId); - $transactionStatus = (string)$data->transaction->transactionStatus; - $fdsFilterAction = (string)$data->transaction->FDSFilterAction; - - if ($payment->getIsTransactionPending()) { - $message = 'Amount of %1 is pending approval on the gateway.
' - . 'Transaction "%2" status is "%3".
' - . 'Transaction FDS Filter Action is "%4"'; - $message = __( - $message, - $payment->getOrder()->getBaseCurrency()->formatTxt($this->getResponse()->getXAmount()), - $transactionId, - $this->dataHelper->getTransactionStatusLabel($transactionStatus), - $this->dataHelper->getFdsFilterActionLabel($fdsFilterAction) - ); - $payment->getOrder()->addStatusHistoryComment($message); - } - } catch (\Exception $e) { - $this->getPsrLogger()->critical($e); - //this request is optional - } - return $this; - } - - /** - * Register order cancellation. Return money to customer if needed. - * - * @param \Magento\Sales\Model\Order $order - * @param string $message - * @param bool $voidPayment - * @return void - */ - protected function declineOrder(\Magento\Sales\Model\Order $order, $message = '', $voidPayment = true) - { - try { - $response = $this->getResponse(); - if ($voidPayment - && $response->getXTransId() - && strtoupper($response->getXType()) == self::REQUEST_TYPE_AUTH_ONLY - ) { - $order->getPayment() - ->setTransactionId(null) - ->setParentTransactionId($response->getXTransId()) - ->void($response); - } - $order->registerCancellation($message)->save(); - $this->_eventManager->dispatch('order_cancel_after', ['order' => $order ]); - } catch (\Exception $e) { - //quiet decline - $this->getPsrLogger()->critical($e); - } - } - - /** - * Return additional information`s transaction_id value of parent transaction model - * - * @param \Magento\Sales\Model\Order\Payment $payment - * @return string - */ - protected function getRealParentTransactionId($payment) - { - $transaction = $this->transactionRepository->getByTransactionId( - $payment->getParentTransactionId(), - $payment->getId(), - $payment->getOrder()->getId() - ); - return $transaction->getAdditionalInformation(self::REAL_TRANSACTION_ID_KEY); - } - - /** - * {inheritdoc} - */ - public function getConfigInterface() - { - return $this; - } - - /** - * Getter for specified value according to set payment method code - * - * @param mixed $key - * @param mixed $storeId - * @return mixed - */ - public function getValue($key, $storeId = null) - { - return $this->getConfigData($key, $storeId); - } - - /** - * Set initialization requirement state - * - * @param bool $isInitializeNeeded - * @return void - */ - public function setIsInitializeNeeded($isInitializeNeeded = true) - { - $this->_isInitializeNeeded = (bool)$isInitializeNeeded; - } - - /** - * Get whether it is possible to capture - * - * @return bool - */ - public function canCapture() - { - return !$this->isGatewayActionsLocked($this->getInfoInstance()); - } - - /** - * Fetch transaction details info - * - * Update transaction info if there is one placing transaction only - * - * @param \Magento\Payment\Model\InfoInterface $payment - * @param string $transactionId - * @return array - */ - public function fetchTransactionInfo(\Magento\Payment\Model\InfoInterface $payment, $transactionId) - { - $transaction = $this->transactionRepository->getByTransactionId( - $transactionId, - $payment->getId(), - $payment->getOrder()->getId() - ); - - $response = $this->getTransactionResponse($transactionId); - if ($response->getXResponseCode() == self::RESPONSE_CODE_APPROVED) { - if ($response->getTransactionStatus() == 'voided') { - $payment->setIsTransactionDenied(true); - $payment->setIsTransactionClosed(true); - $transaction->close(); - } else { - $transaction->setAdditionalInformation(self::TRANSACTION_FRAUD_STATE_KEY, false); - $payment->setIsTransactionApproved(true); - } - } elseif ($response->getXResponseReasonCode() == self::RESPONSE_REASON_CODE_PENDING_REVIEW_DECLINED) { - $payment->setIsTransactionDenied(true); - } - $this->addStatusCommentOnUpdate($payment, $response, $transactionId); - return $response->getData(); - } - - /** - * Add status comment on update - * - * @param \Magento\Sales\Model\Order\Payment $payment - * @param \Magento\Framework\DataObject $response - * @param string $transactionId - * @return $this - */ - protected function addStatusCommentOnUpdate( - \Magento\Sales\Model\Order\Payment $payment, - \Magento\Framework\DataObject $response, - $transactionId - ) { - if ($payment->getIsTransactionApproved()) { - $message = __( - 'Transaction %1 has been approved. Amount %2. Transaction status is "%3"', - $transactionId, - $payment->getOrder()->getBaseCurrency()->formatTxt($payment->getAmountAuthorized()), - $this->dataHelper->getTransactionStatusLabel($response->getTransactionStatus()) - ); - $payment->getOrder()->addStatusHistoryComment($message); - } elseif ($payment->getIsTransactionDenied()) { - $message = __( - 'Transaction %1 has been voided/declined. Transaction status is "%2". Amount %3.', - $transactionId, - $this->dataHelper->getTransactionStatusLabel($response->getTransactionStatus()), - $payment->getOrder()->getBaseCurrency()->formatTxt($payment->getAmountAuthorized()) - ); - $payment->getOrder()->addStatusHistoryComment($message); - } - return $this; - } - - /** - * Sets method code - * - * @param string $methodCode - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @return void - */ - public function setMethodCode($methodCode) - { - } - - /** - * Sets path pattern - * - * @param string $pathPattern - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - * @return void - */ - public function setPathPattern($pathPattern) - { - } - - /** - * This function returns full transaction details for a specified transaction ID. - * - * @param string $transactionId - * @return \Magento\Framework\DataObject - * @throws \Magento\Framework\Exception\LocalizedException - * @link http://www.authorize.net/support/ReportingGuide_XML.pdf - * @link http://developer.authorize.net/api/transaction_details/ - */ - protected function getTransactionResponse($transactionId) - { - $responseXmlDocument = $this->transactionService->getTransactionDetails($this, $transactionId); - - $response = new \Magento\Framework\DataObject(); - $response->setXResponseCode((string)$responseXmlDocument->transaction->responseCode) - ->setXResponseReasonCode((string)$responseXmlDocument->transaction->responseReasonCode) - ->setTransactionStatus((string)$responseXmlDocument->transaction->transactionStatus); - - return $response; - } - - /** - * Get psr logger. - * - * @return \Psr\Log\LoggerInterface - * @deprecated 100.1.0 - */ - private function getPsrLogger() - { - if (null === $this->psrLogger) { - $this->psrLogger = ObjectManager::getInstance() - ->get(\Psr\Log\LoggerInterface::class); - } - return $this->psrLogger; - } - - /** - * Fetch order by increment id from response. - * - * @return \Magento\Sales\Model\Order - */ - private function getOrderFromResponse(): \Magento\Sales\Model\Order - { - if (!$this->order) { - $this->order = $this->orderFactory->create(); - - if ($incrementId = $this->getOrderIncrementId()) { - $this->order = $this->order->loadByIncrementId($incrementId); - } - } - - return $this->order; - } - - /** - * Fetch order increment id from response. - * - * @return string - */ - private function getOrderIncrementId(): string - { - return $this->getResponse()->getXInvoiceNum(); - } - - /** - * Checks if filter action is Report Only. - * - * Transactions that trigger this filter are processed as normal, - * but are also reported in the Merchant Interface as triggering this filter. - * - * @param string $fdsFilterAction - * @return bool - */ - private function fdsFilterActionIsReportOnly($fdsFilterAction) - { - return $fdsFilterAction === (string)$this->dataHelper->getFdsFilterActionLabel('report'); - } -} diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Request.php b/app/code/Magento/Authorizenet/Model/Directpost/Request.php deleted file mode 100644 index 10be4cd5febf6..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Directpost/Request.php +++ /dev/null @@ -1,280 +0,0 @@ -dateTimeFactory = $dateTimeFactory ?? ObjectManager::getInstance() - ->get(DateTimeFactory::class); - parent::__construct($data); - } - - /** - * Return merchant transaction key. - * - * Needed to generate MD5 sign. - * - * @return string - */ - protected function _getTransactionKey() - { - return $this->_transKey; - } - - /** - * Set merchant transaction key. - * - * Needed to generate MD5 sign. - * - * @param string $transKey - * @return $this - */ - protected function _setTransactionKey($transKey) - { - $this->_transKey = $transKey; - return $this; - } - - /** - * Generates the MD5 fingerprint for request. - * - * @param string $merchantApiLoginId - * @param string $merchantTransactionKey - * @param string $amount - * @param string $currencyCode - * @param string $fpSequence An invoice number or random number. - * @param string $fpTimestamp - * @return string The fingerprint. - */ - public function generateRequestSign( - $merchantApiLoginId, - $merchantTransactionKey, - $amount, - $currencyCode, - $fpSequence, - $fpTimestamp - ) { - return hash_hmac( - "md5", - $merchantApiLoginId . '^' . $fpSequence . '^' . $fpTimestamp . '^' . $amount . '^' . $currencyCode, - $merchantTransactionKey - ); - } - - /** - * Set Authorizenet data to request. - * - * @param \Magento\Authorizenet\Model\Directpost $paymentMethod - * @return $this - */ - public function setConstantData(\Magento\Authorizenet\Model\Directpost $paymentMethod) - { - $this->setXVersion('3.1')->setXDelimData('FALSE')->setXRelayResponse('TRUE'); - - $this->setSignatureKey($paymentMethod->getConfigData('signature_key')); - - $this->setXLogin($paymentMethod->getConfigData('login')) - ->setXMethod(\Magento\Authorizenet\Model\Authorizenet::REQUEST_METHOD_CC) - ->setXRelayUrl($paymentMethod->getRelayUrl()); - - $this->_setTransactionKey($paymentMethod->getConfigData('trans_key')); - return $this; - } - - /** - * Set entity data to request - * - * @param \Magento\Sales\Model\Order $order - * @param \Magento\Authorizenet\Model\Directpost $paymentMethod - * @return $this - */ - public function setDataFromOrder( - \Magento\Sales\Model\Order $order, - \Magento\Authorizenet\Model\Directpost $paymentMethod - ) { - $payment = $order->getPayment(); - - $this->setXType($payment->getAnetTransType()); - $this->setXFpSequence($order->getQuoteId()); - $this->setXInvoiceNum($order->getIncrementId()); - $this->setXAmount($payment->getBaseAmountAuthorized()); - $this->setXCurrencyCode($order->getBaseCurrencyCode()); - $this->setXTax( - sprintf('%.2F', $order->getBaseTaxAmount()) - )->setXFreight( - sprintf('%.2F', $order->getBaseShippingAmount()) - ); - - //need to use (string) because NULL values IE6-8 decodes as "null" in JSON in JavaScript, - //but we need "" for null values. - $billing = $order->getBillingAddress(); - if (!empty($billing)) { - $this->setXFirstName((string)$billing->getFirstname()) - ->setXLastName((string)$billing->getLastname()) - ->setXCompany((string)$billing->getCompany()) - ->setXAddress((string)$billing->getStreetLine(1)) - ->setXCity((string)$billing->getCity()) - ->setXState((string)$billing->getRegion()) - ->setXZip((string)$billing->getPostcode()) - ->setXCountry((string)$billing->getCountryId()) - ->setXPhone((string)$billing->getTelephone()) - ->setXFax((string)$billing->getFax()) - ->setXCustId((string)$billing->getCustomerId()) - ->setXCustomerIp((string)$order->getRemoteIp()) - ->setXCustomerTaxId((string)$billing->getTaxId()) - ->setXEmail((string)$order->getCustomerEmail()) - ->setXEmailCustomer((string)$paymentMethod->getConfigData('email_customer')) - ->setXMerchantEmail((string)$paymentMethod->getConfigData('merchant_email')); - } - - $shipping = $order->getShippingAddress(); - if (!empty($shipping)) { - $this->setXShipToFirstName( - (string)$shipping->getFirstname() - )->setXShipToLastName( - (string)$shipping->getLastname() - )->setXShipToCompany( - (string)$shipping->getCompany() - )->setXShipToAddress( - (string)$shipping->getStreetLine(1) - )->setXShipToCity( - (string)$shipping->getCity() - )->setXShipToState( - (string)$shipping->getRegion() - )->setXShipToZip( - (string)$shipping->getPostcode() - )->setXShipToCountry( - (string)$shipping->getCountryId() - ); - } - - $this->setXPoNum((string)$payment->getPoNumber()); - - return $this; - } - - /** - * Set sign hash into the request object. - * - * All needed fields should be placed in the object first. - * - * @return $this - */ - public function signRequestData() - { - $fpDate = $this->dateTimeFactory->create('now', new \DateTimeZone('UTC')); - $fpTimestamp = $fpDate->getTimestamp(); - - if (!empty($this->getSignatureKey())) { - $hash = $this->generateSha2RequestSign( - (string)$this->getXLogin(), - (string)$this->getSignatureKey(), - (string)$this->getXAmount(), - (string)$this->getXCurrencyCode(), - (string)$this->getXFpSequence(), - $fpTimestamp - ); - } else { - $hash = $this->generateRequestSign( - $this->getXLogin(), - $this->_getTransactionKey(), - $this->getXAmount(), - $this->getXCurrencyCode(), - $this->getXFpSequence(), - $fpTimestamp - ); - } - - $this->setXFpTimestamp($fpTimestamp); - $this->setXFpHash($hash); - - return $this; - } - - /** - * Generates the SHA2 fingerprint for request. - * - * @param string $merchantApiLoginId - * @param string $merchantSignatureKey - * @param string $amount - * @param string $currencyCode - * @param string $fpSequence An invoice number or random number. - * @param int $fpTimestamp - * @return string The fingerprint. - */ - private function generateSha2RequestSign( - string $merchantApiLoginId, - string $merchantSignatureKey, - string $amount, - string $currencyCode, - string $fpSequence, - int $fpTimestamp - ): string { - $message = $merchantApiLoginId . '^' . $fpSequence . '^' . $fpTimestamp . '^' . $amount . '^' . $currencyCode; - - return strtoupper(hash_hmac('sha512', $message, pack('H*', $merchantSignatureKey))); - } - - /** - * Return merchant hexadecimal signature key. - * - * Needed to generate SHA2 sign. - * - * @return string - */ - private function getSignatureKey(): string - { - return $this->signatureKey; - } - - /** - * Set merchant hexadecimal signature key. - * - * Needed to generate SHA2 sign. - * - * @param string $signatureKey - * @return void - */ - private function setSignatureKey(string $signatureKey) - { - $this->signatureKey = $signatureKey; - } -} diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Request/Factory.php b/app/code/Magento/Authorizenet/Model/Directpost/Request/Factory.php deleted file mode 100644 index 6036935f57be1..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Directpost/Request/Factory.php +++ /dev/null @@ -1,30 +0,0 @@ -getData('x_amount'))) { - $this->setData('x_amount', '0.00'); - } - - if (!empty($this->getData('x_SHA2_Hash'))) { - $hash = $this->generateSha2Hash($storedHash); - return Security::compareStrings($hash, $this->getData('x_SHA2_Hash')); - } elseif (!empty($this->getData('x_MD5_Hash'))) { - $hash = $this->generateHash($storedHash, $merchantApiLogin, $this->getXAmount(), $this->getXTransId()); - return Security::compareStrings($hash, $this->getData('x_MD5_Hash')); - } - - return false; - } - - /** - * Return if this is approved response from Authorize.net auth request. - * - * @return bool - */ - public function isApproved() - { - return $this->getXResponseCode() == \Magento\Authorizenet\Model\Directpost::RESPONSE_CODE_APPROVED; - } - - /** - * Generates an SHA2 hash to compare against AuthNet's. - * - * @param string $signatureKey - * @return string - * @see https://support.authorize.net/s/article/MD5-Hash-End-of-Life-Signature-Key-Replacement - */ - private function generateSha2Hash(string $signatureKey): string - { - $hashFields = [ - 'x_trans_id', - 'x_test_request', - 'x_response_code', - 'x_auth_code', - 'x_cvv2_resp_code', - 'x_cavv_response', - 'x_avs_code', - 'x_method', - 'x_account_number', - 'x_amount', - 'x_company', - 'x_first_name', - 'x_last_name', - 'x_address', - 'x_city', - 'x_state', - 'x_zip', - 'x_country', - 'x_phone', - 'x_fax', - 'x_email', - 'x_ship_to_company', - 'x_ship_to_first_name', - 'x_ship_to_last_name', - 'x_ship_to_address', - 'x_ship_to_city', - 'x_ship_to_state', - 'x_ship_to_zip', - 'x_ship_to_country', - 'x_invoice_num', - ]; - - $message = '^'; - foreach ($hashFields as $field) { - $message .= ($this->getData($field) ?? '') . '^'; - } - - return strtoupper(hash_hmac('sha512', $message, pack('H*', $signatureKey))); - } -} diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Response/Factory.php b/app/code/Magento/Authorizenet/Model/Directpost/Response/Factory.php deleted file mode 100644 index 4fda5ac62b498..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Directpost/Response/Factory.php +++ /dev/null @@ -1,30 +0,0 @@ -getDirectPostOrderIncrementIds(); - if (!$orderIncIds) { - $orderIncIds = []; - } - $orderIncIds[$orderIncrementId] = 1; - $this->setDirectPostOrderIncrementIds($orderIncIds); - } - - /** - * Remove order IncrementId from session - * - * @param string $orderIncrementId - * @return void - */ - public function removeCheckoutOrderIncrementId($orderIncrementId) - { - $orderIncIds = $this->getDirectPostOrderIncrementIds(); - - if (!is_array($orderIncIds)) { - return; - } - - if (isset($orderIncIds[$orderIncrementId])) { - unset($orderIncIds[$orderIncrementId]); - } - $this->setDirectPostOrderIncrementIds($orderIncIds); - } - - /** - * Return if order incrementId is in session. - * - * @param string $orderIncrementId - * @return bool - */ - public function isCheckoutOrderIncrementIdExist($orderIncrementId) - { - $orderIncIds = $this->getDirectPostOrderIncrementIds(); - if (is_array($orderIncIds) && isset($orderIncIds[$orderIncrementId])) { - return true; - } - return false; - } - - /** - * Set quote id to session - * - * @param int|string $id - * @return $this - */ - public function setQuoteId($id) - { - $this->storage->setQuoteId($id); - return $this; - } -} diff --git a/app/code/Magento/Authorizenet/Model/Request.php b/app/code/Magento/Authorizenet/Model/Request.php deleted file mode 100644 index 552439fc8bb9b..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Request.php +++ /dev/null @@ -1,18 +0,0 @@ -objectManager = $objectManager; - $this->instanceName = $instanceName; - } - - /** - * Create class instance with specified parameters - * - * @param array $data - * @return \Magento\Authorizenet\Model\Request - */ - public function create(array $data = []) - { - return $this->objectManager->create($this->instanceName, $data); - } -} diff --git a/app/code/Magento/Authorizenet/Model/ResourceModel/Debug.php b/app/code/Magento/Authorizenet/Model/ResourceModel/Debug.php deleted file mode 100644 index 2c21d0e2e28e0..0000000000000 --- a/app/code/Magento/Authorizenet/Model/ResourceModel/Debug.php +++ /dev/null @@ -1,25 +0,0 @@ -_init('authorizenet_debug', 'debug_id'); - } -} diff --git a/app/code/Magento/Authorizenet/Model/ResourceModel/Debug/Collection.php b/app/code/Magento/Authorizenet/Model/ResourceModel/Debug/Collection.php deleted file mode 100644 index b84ee1e72a2d4..0000000000000 --- a/app/code/Magento/Authorizenet/Model/ResourceModel/Debug/Collection.php +++ /dev/null @@ -1,28 +0,0 @@ -_init( - \Magento\Authorizenet\Model\Debug::class, - \Magento\Authorizenet\Model\ResourceModel\Debug::class - ); - } -} diff --git a/app/code/Magento/Authorizenet/Model/Response.php b/app/code/Magento/Authorizenet/Model/Response.php deleted file mode 100644 index c552663a15373..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Response.php +++ /dev/null @@ -1,18 +0,0 @@ -objectManager = $objectManager; - $this->instanceName = $instanceName; - } - - /** - * Create class instance with specified parameters - * - * @param array $data - * @return \Magento\Authorizenet\Model\Response - */ - public function create(array $data = []) - { - return $this->objectManager->create($this->instanceName, $data); - } -} diff --git a/app/code/Magento/Authorizenet/Model/Source/Cctype.php b/app/code/Magento/Authorizenet/Model/Source/Cctype.php deleted file mode 100644 index ffb3584722450..0000000000000 --- a/app/code/Magento/Authorizenet/Model/Source/Cctype.php +++ /dev/null @@ -1,27 +0,0 @@ - \Magento\Authorizenet\Model\Authorizenet::ACTION_AUTHORIZE, - 'label' => __('Authorize Only'), - ], - [ - 'value' => \Magento\Authorizenet\Model\Authorizenet::ACTION_AUTHORIZE_CAPTURE, - 'label' => __('Authorize and Capture') - ] - ]; - } -} diff --git a/app/code/Magento/Authorizenet/Model/TransactionService.php b/app/code/Magento/Authorizenet/Model/TransactionService.php deleted file mode 100644 index af0b02e94cf45..0000000000000 --- a/app/code/Magento/Authorizenet/Model/TransactionService.php +++ /dev/null @@ -1,183 +0,0 @@ -xmlSecurityHelper = $xmlSecurityHelper; - $this->logger = $logger; - $this->httpClientFactory = $httpClientFactory; - } - - /** - * Get transaction information - * - * @param \Magento\Authorizenet\Model\Authorizenet $context - * @param string $transactionId - * @return \Magento\Framework\Simplexml\Element - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function getTransactionDetails(Authorizenet $context, $transactionId) - { - return isset($this->transactionDetails[$transactionId]) - ? $this->transactionDetails[$transactionId] - : $this->loadTransactionDetails($context, $transactionId); - } - - /** - * Load transaction details - * - * @param \Magento\Authorizenet\Model\Authorizenet $context - * @param string $transactionId - * @return \Magento\Framework\Simplexml\Element - * @throws \Magento\Framework\Exception\LocalizedException - */ - protected function loadTransactionDetails(Authorizenet $context, $transactionId) - { - - $requestBody = $this->getRequestBody( - $context->getConfigData('login'), - $context->getConfigData('trans_key'), - $transactionId - ); - - /** @var \Magento\Framework\HTTP\ZendClient $client */ - $client = $this->httpClientFactory->create(); - $url = $context->getConfigData('cgi_url_td') ?: self::CGI_URL_TD; - $client->setUri($url); - $client->setConfig(['timeout' => self::CONNECTION_TIMEOUT]); - $client->setHeaders(['Content-Type: text/xml']); - $client->setMethod(\Zend_Http_Client::POST); - $client->setRawData($requestBody); - - $debugData = ['url' => $url, 'request' => $this->removePrivateDataFromXml($requestBody)]; - - try { - $responseBody = $client->request()->getBody(); - if (!$this->xmlSecurityHelper->scan($responseBody)) { - $this->logger->critical('Attempt loading of external XML entities in response from Authorizenet.'); - throw new \Exception(); - } - $debugData['response'] = $responseBody; - libxml_use_internal_errors(true); - $responseXmlDocument = new Element($responseBody); - libxml_use_internal_errors(false); - } catch (\Exception $e) { - throw new LocalizedException(__('The transaction details are unavailable. Please try again later.')); - } finally { - $context->debugData($debugData); - } - - if (!isset($responseXmlDocument->messages->resultCode) - || $responseXmlDocument->messages->resultCode != static::PAYMENT_UPDATE_STATUS_CODE_SUCCESS - ) { - throw new LocalizedException(__('The transaction details are unavailable. Please try again later.')); - } - - $this->transactionDetails[$transactionId] = $responseXmlDocument; - return $responseXmlDocument; - } - - /** - * Create request body to get transaction details - * - * @param string $login - * @param string $transactionKey - * @param string $transactionId - * @return string - */ - private function getRequestBody($login, $transactionKey, $transactionId) - { - $requestBody = sprintf( - '' . - '' . - '%s%s' . - '%s' . - '', - $login, - $transactionKey, - $transactionId - ); - return $requestBody; - } - - /** - * Remove nodes with private data from XML string - * - * Uses values from $_debugReplacePrivateDataKeys property - * - * @param string $xml - * @return string - */ - private function removePrivateDataFromXml($xml) - { - foreach ($this->debugReplacePrivateDataKeys as $key) { - $xml = preg_replace(sprintf('~(?<=<%s>).*?(?=)~', $key, $key), Logger::DEBUG_KEYS_MASK, $xml); - } - return $xml; - } -} diff --git a/app/code/Magento/Authorizenet/Observer/AddFieldsToResponseObserver.php b/app/code/Magento/Authorizenet/Observer/AddFieldsToResponseObserver.php deleted file mode 100644 index bdd10437927c8..0000000000000 --- a/app/code/Magento/Authorizenet/Observer/AddFieldsToResponseObserver.php +++ /dev/null @@ -1,109 +0,0 @@ -coreRegistry = $coreRegistry; - $this->payment = $payment; - $this->session = $session; - $this->storeManager = $storeManager; - } - - /** - * Save order into registry to use it in the overloaded controller. - * - * @param \Magento\Framework\Event\Observer $observer - * @return $this - */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - /* @var $order Order */ - $order = $this->coreRegistry->registry('directpost_order'); - - if (!$order || !$order->getId()) { - return $this; - } - - $payment = $order->getPayment(); - - if (!$payment || $payment->getMethod() != $this->payment->getCode()) { - return $this; - } - - $result = $observer->getData('result')->getData(); - - if (!empty($result['error'])) { - return $this; - } - - // if success, then set order to session and add new fields - $this->session->addCheckoutOrderIncrementId($order->getIncrementId()); - $this->session->setLastOrderIncrementId($order->getIncrementId()); - - $requestToAuthorizenet = $payment->getMethodInstance() - ->generateRequestFromOrder($order); - $requestToAuthorizenet->setControllerActionName( - $observer->getData('action') - ->getRequest() - ->getControllerName() - ); - $requestToAuthorizenet->setIsSecure( - (string)$this->storeManager->getStore() - ->isCurrentlySecure() - ); - - $result[$this->payment->getCode()] = ['fields' => $requestToAuthorizenet->getData()]; - - $observer->getData('result')->setData($result); - - return $this; - } -} diff --git a/app/code/Magento/Authorizenet/Observer/SaveOrderAfterSubmitObserver.php b/app/code/Magento/Authorizenet/Observer/SaveOrderAfterSubmitObserver.php deleted file mode 100644 index 45f0adfa96f4f..0000000000000 --- a/app/code/Magento/Authorizenet/Observer/SaveOrderAfterSubmitObserver.php +++ /dev/null @@ -1,48 +0,0 @@ -coreRegistry = $coreRegistry; - } - - /** - * Save order into registry to use it in the overloaded controller. - * - * @param \Magento\Framework\Event\Observer $observer - * @return $this - */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - /* @var $order Order */ - $order = $observer->getEvent()->getData('order'); - $this->coreRegistry->register('directpost_order', $order, true); - - return $this; - } -} diff --git a/app/code/Magento/Authorizenet/Observer/UpdateAllEditIncrementsObserver.php b/app/code/Magento/Authorizenet/Observer/UpdateAllEditIncrementsObserver.php deleted file mode 100644 index d6cc51eb63c01..0000000000000 --- a/app/code/Magento/Authorizenet/Observer/UpdateAllEditIncrementsObserver.php +++ /dev/null @@ -1,48 +0,0 @@ -authorizenetData = $authorizenetData; - } - - /** - * Save order into registry to use it in the overloaded controller. - * - * @param \Magento\Framework\Event\Observer $observer - * @return $this - */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - /* @var $order Order */ - $order = $observer->getEvent()->getData('order'); - $this->authorizenetData->updateOrderEditIncrements($order); - - return $this; - } -} diff --git a/app/code/Magento/Authorizenet/README.md b/app/code/Magento/Authorizenet/README.md deleted file mode 100644 index 62598837bee6d..0000000000000 --- a/app/code/Magento/Authorizenet/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Magento_Authorizenet module - -The Magento_Authorizenet module implements the integration with the Authorize.Net payment gateway and makes the latter available as a payment method in Magento. - -## Extensibility - -Extension developers can interact with the Magento_Authorizenet module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). - -[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_Authorizenet module. - -### Events - -This module dispatches the following events: - - - `checkout_directpost_placeOrder` event in the `\Magento\Authorizenet\Controller\Directpost\Payment\Place::placeCheckoutOrder()` method. Parameters: - - `result` is a data object (`\Magento\Framework\DataObject` class). - - `action` is a controller object (`\Magento\Authorizenet\Controller\Directpost\Payment\Place`). - - - `order_cancel_after` event in the `\Magento\Authorizenet\Model\Directpost::declineOrder()` method. Parameters: - - `order` is an order object (`\Magento\Sales\Model\Order` class). - - -This module observes the following events: - - - `checkout_submit_all_after` event in the `Magento\Authorizenet\Observer\SaveOrderAfterSubmitObserver` file. - - `checkout_directpost_placeOrder` event in the `Magento\Authorizenet\Observer\AddFieldsToResponseObserver` file. - -For information about events in Magento 2, see [Events and observers](http://devdocs.magento.com/guides/v2.3/extension-dev-guide/events-and-observers.html#events). - -### Layouts - -This module introduces the following layouts and layout handles in the `view/adminhtml/layout` directory: - -- `adminhtml_authorizenet_directpost_payment_redirect` - -This module introduces the following layouts and layout handles in the `view/frontend/layout` directory: - -- `authorizenet_directpost_payment_backendresponse` -- `authorizenet_directpost_payment_redirect` -- `authorizenet_directpost_payment_response` - -For more information about layouts in Magento 2, see the [Layout documentation](https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/layouts/layout-overview.html). diff --git a/app/code/Magento/Authorizenet/Test/Mftf/README.md b/app/code/Magento/Authorizenet/Test/Mftf/README.md deleted file mode 100644 index 9391126a85c94..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Mftf/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Authorizenet Functional Tests - -The Functional Test Module for **Magento Authorizenet** module. diff --git a/app/code/Magento/Authorizenet/Test/Unit/Controller/Adminhtml/Authorizenet/Directpost/Payment/RedirectTest.php b/app/code/Magento/Authorizenet/Test/Unit/Controller/Adminhtml/Authorizenet/Directpost/Payment/RedirectTest.php deleted file mode 100644 index b26c9bf22f153..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Controller/Adminhtml/Authorizenet/Directpost/Payment/RedirectTest.php +++ /dev/null @@ -1,312 +0,0 @@ -directpostSessionMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost\Session::class) - ->setMethods([ - 'getLastOrderIncrementId', - 'removeCheckoutOrderIncrementId', - 'isCheckoutOrderIncrementIdExist', - 'unsetData' - ]) - ->disableOriginalConstructor() - ->getMock(); - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $this->orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->setMethods(['getId', 'getState', 'getIncrementId', 'registerCancellation', 'loadByIncrementId', 'save']) - ->disableOriginalConstructor() - ->getMock(); - $this->adminOrderCreateMock = $this->getMockBuilder(\Magento\Sales\Model\AdminOrder\Create::class) - ->setMethods(['getSession']) - ->disableOriginalConstructor() - ->getMock(); - $sessionMock = $this->getMockBuilder(\Magento\Backend\Model\Session::class) - ->disableOriginalConstructor() - ->getMock(); - $this->sessionQuoteMock = $this->getMockBuilder(\Magento\Backend\Model\Session\Quote::class) - ->setMethods(['getOrder', 'clearStorage']) - ->disableOriginalConstructor() - ->getMock(); - $this->objectManagerMock->expects($this->atLeastOnce()) - ->method('get') - ->willReturnMap([ - [\Magento\Authorizenet\Model\Directpost\Session::class, $this->directpostSessionMock], - [\Magento\Sales\Model\AdminOrder\Create::class, $this->adminOrderCreateMock], - [\Magento\Backend\Model\Session\Quote::class, $this->sessionQuoteMock], - [\Magento\Backend\Model\Session::class, $sessionMock], - ]); - $this->objectManagerMock->expects($this->any()) - ->method('create') - ->with(\Magento\Sales\Model\Order::class) - ->willReturn($this->orderMock); - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->setMethods(['getParams']) - ->getMockForAbstractClass(); - $responseMock = $this->getMockForAbstractClass(\Magento\Framework\App\ResponseInterface::class); - $redirectMock = $this->createMock(\Magento\Framework\App\Response\RedirectInterface::class); - $this->messageManagerMock = $this->createMock(\Magento\Framework\Message\ManagerInterface::class); - - $this->contextMock = $this->getMockBuilder(\Magento\Backend\App\Action\Context::class) - ->setMethods(['getObjectManager', 'getRequest', 'getResponse', 'getRedirect', 'getMessageManager']) - ->disableOriginalConstructor() - ->getMock(); - $this->contextMock->expects($this->any())->method('getObjectManager')->willReturn($this->objectManagerMock); - $this->contextMock->expects($this->any())->method('getRequest')->willReturn($this->requestMock); - $this->contextMock->expects($this->any())->method('getResponse')->willReturn($responseMock); - $this->contextMock->expects($this->any())->method('getRedirect')->willReturn($redirectMock); - $this->contextMock->expects($this->any())->method('getMessageManager')->willReturn($this->messageManagerMock); - - $this->productHelperMock = $this->getMockBuilder(\Magento\Catalog\Helper\Product::class) - ->disableOriginalConstructor() - ->getMock(); - $this->escaperMock = $this->getMockBuilder(\Magento\Framework\Escaper::class) - ->disableOriginalConstructor() - ->getMock(); - $this->resultPageFactoryMock = $this->getMockBuilder(\Magento\Framework\View\Result\PageFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->forwardFactoryMock = $this->getMockBuilder(\Magento\Backend\Model\View\Result\ForwardFactory::class) - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $this->coreRegistryMock = $this->getMockBuilder(\Magento\Framework\Registry::class) - ->setMethods(['register']) - ->disableOriginalConstructor() - ->getMock(); - $resultLayoutMock = $this->getMockBuilder(\Magento\Framework\View\Result\Layout::class) - ->disableOriginalConstructor() - ->getMock(); - $this->resultLayoutFactoryMock = $this->getMockBuilder(\Magento\Framework\View\Result\LayoutFactory::class) - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $this->resultLayoutFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($resultLayoutMock); - $this->helperMock = $this->getMockBuilder(\Magento\Authorizenet\Helper\Backend\Data::class) - ->setMethods(['getSuccessOrderUrl']) - ->disableOriginalConstructor() - ->getMock(); - - $this->controller = new Redirect( - $this->contextMock, - $this->productHelperMock, - $this->escaperMock, - $this->resultPageFactoryMock, - $this->forwardFactoryMock, - $this->coreRegistryMock, - $this->resultLayoutFactoryMock, - $this->helperMock - ); - } - - public function testExecuteErrorMsgWithoutCancelOrder() - { - $params = ['success' => 0, 'error_msg' => 'Error message']; - $incrementId = 1; - $this->requestMock->expects($this->once()) - ->method('getParams') - ->willReturn($params); - $this->directpostSessionMock->expects($this->once()) - ->method('getLastOrderIncrementId') - ->willReturn($incrementId); - $this->directpostSessionMock->expects($this->once()) - ->method('isCheckoutOrderIncrementIdExist') - ->with($incrementId) - ->willReturn(true); - - $this->orderMock->expects($this->once()) - ->method('loadByIncrementId') - ->with($incrementId) - ->willReturnSelf(); - $this->orderMock->expects($this->once()) - ->method('getId') - ->willReturn(true); - $this->orderMock->expects($this->once()) - ->method('getIncrementId') - ->willReturn($incrementId); - $this->orderMock->expects($this->once()) - ->method('getState') - ->willReturn(\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT); - $this->orderMock->expects($this->once()) - ->method('registerCancellation') - ->with($params['error_msg']) - ->willReturnSelf(); - $this->orderMock->expects($this->once()) - ->method('save'); - - $this->directpostSessionMock->expects($this->once()) - ->method('removeCheckoutOrderIncrementId') - ->with($incrementId); - $this->coreRegistryMock->expects($this->once()) - ->method('register') - ->with(Iframe::REGISTRY_KEY); - - $this->assertInstanceOf(\Magento\Framework\View\Result\Layout::class, $this->controller->execute()); - } - - public function testExecuteErrorMsgWithCancelOrder() - { - $params = ['success' => 0, 'error_msg' => 'Error message', 'x_invoice_num' => 1]; - $incrementId = 1; - $this->requestMock->expects($this->once()) - ->method('getParams') - ->willReturn($params); - $this->directpostSessionMock->expects($this->once()) - ->method('getLastOrderIncrementId') - ->willReturn($incrementId); - $this->directpostSessionMock->expects($this->once()) - ->method('isCheckoutOrderIncrementIdExist') - ->with($incrementId) - ->willReturn(true); - $this->orderMock->expects($this->once()) - ->method('loadByIncrementId') - ->with($incrementId) - ->willReturnSelf(); - $this->orderMock->expects($this->once()) - ->method('getId') - ->willReturn(true); - $this->orderMock->expects($this->once()) - ->method('getIncrementId') - ->willReturn($incrementId); - $this->directpostSessionMock->expects($this->once()) - ->method('removeCheckoutOrderIncrementId') - ->with($incrementId); - - $this->coreRegistryMock->expects($this->once()) - ->method('register') - ->with(Iframe::REGISTRY_KEY); - - $this->assertInstanceOf(\Magento\Framework\View\Result\Layout::class, $this->controller->execute()); - } - - public function testExecuteSuccess() - { - $params = ['success' => 1, 'controller_action_name' => 'action', 'x_invoice_num' => 1]; - $this->requestMock->expects($this->once()) - ->method('getParams') - ->willReturn($params); - - $this->helperMock->expects($this->once()) - ->method('getSuccessOrderUrl') - ->willReturn('redirect_parent_url'); - - $this->directpostSessionMock->expects($this->once()) - ->method('unsetData') - ->with('quote_id'); - - $this->orderMock->expects($this->once()) - ->method('getId') - ->willReturn(null); - - $this->sessionQuoteMock->expects($this->atLeastOnce()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->adminOrderCreateMock->expects($this->atLeastOnce()) - ->method('getSession') - ->willReturn($this->sessionQuoteMock); - - $this->coreRegistryMock->expects($this->once()) - ->method('register') - ->with(Iframe::REGISTRY_KEY); - - $this->assertInstanceOf(\Magento\Framework\View\Result\Layout::class, $this->controller->execute()); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Controller/Directpost/Payment/PlaceTest.php b/app/code/Magento/Authorizenet/Test/Unit/Controller/Directpost/Payment/PlaceTest.php deleted file mode 100644 index c0a50e66759ba..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Controller/Directpost/Payment/PlaceTest.php +++ /dev/null @@ -1,332 +0,0 @@ -directpostSessionMock = $this - ->getMockBuilder(\Magento\Authorizenet\Model\Directpost\Session::class) - ->disableOriginalConstructor() - ->getMock(); - $this->quoteMock = $this - ->getMockBuilder(\Magento\Quote\Model\Quote::class) - ->disableOriginalConstructor() - ->getMock(); - $this->checkoutSessionMock = $this - ->getMockBuilder(\Magento\Checkout\Model\Session::class) - ->disableOriginalConstructor() - ->getMock(); - $this->checkoutSessionMock->expects($this->any()) - ->method('getQuote') - ->will($this->returnValue($this->quoteMock)); - $this->objectManagerMock = $this - ->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) - ->getMockForAbstractClass(); - $this->objectManagerMock->expects($this->any()) - ->method('get') - ->willReturnMap([ - [\Magento\Authorizenet\Model\Directpost\Session::class, $this->directpostSessionMock], - [\Magento\Checkout\Model\Session::class, $this->checkoutSessionMock], - ]); - $this->coreRegistryMock = $this - ->getMockBuilder(\Magento\Framework\Registry::class) - ->disableOriginalConstructor() - ->getMock(); - $this->dataFactoryMock = $this - ->getMockBuilder(\Magento\Authorizenet\Helper\DataFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->cartManagementMock = $this - ->getMockBuilder(\Magento\Quote\Api\CartManagementInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->onepageCheckout = $this - ->getMockBuilder(\Magento\Checkout\Model\Type\Onepage::class) - ->disableOriginalConstructor() - ->getMock(); - $this->jsonHelperMock = $this - ->getMockBuilder(\Magento\Framework\Json\Helper\Data::class) - ->disableOriginalConstructor() - ->getMock(); - $this->requestMock = $this - ->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->getMockForAbstractClass(); - $this->responseMock = $this - ->getMockBuilder(\Magento\Framework\App\Response\Http::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->loggerMock = $this - ->getMockBuilder(\Psr\Log\LoggerInterface::class) - ->getMock(); - - $this->objectManager = new ObjectManager($this); - $this->placeOrderController = $this->objectManager->getObject( - \Magento\Authorizenet\Controller\Directpost\Payment\Place::class, - [ - 'request' => $this->requestMock, - 'response' => $this->responseMock, - 'objectManager' => $this->objectManagerMock, - 'coreRegistry' => $this->coreRegistryMock, - 'dataFactory' => $this->dataFactoryMock, - 'cartManagement' => $this->cartManagementMock, - 'onepageCheckout' => $this->onepageCheckout, - 'jsonHelper' => $this->jsonHelperMock, - 'logger' => $this->loggerMock, - ] - ); - } - - /** - * @param $paymentMethod - * @param $controller - * @param $quoteId - * @param $orderId - * @param $result - * @dataProvider textExecuteDataProvider - */ - public function testExecute( - $paymentMethod, - $controller, - $quoteId, - $orderId, - $result - ) { - $this->requestMock->expects($this->at(0)) - ->method('getParam') - ->with('payment') - ->will($this->returnValue($paymentMethod)); - - $this->requestMock->expects($this->at(1)) - ->method('getParam') - ->with('controller') - ->will($this->returnValue($controller)); - - $this->quoteMock->expects($this->any()) - ->method('getId') - ->will($this->returnValue($quoteId)); - - $this->cartManagementMock->expects($this->any()) - ->method('placeOrder') - ->will($this->returnValue($orderId)); - - $this->jsonHelperMock->expects($this->any()) - ->method('jsonEncode') - ->with($result); - - $this->placeOrderController->execute(); - } - - /** - * @param $paymentMethod - * @param $controller - * @param $quoteId - * @param $result - * @param \Exception $exception Exception to check - * @dataProvider textExecuteFailedPlaceOrderDataProvider - */ - public function testExecuteFailedPlaceOrder( - $paymentMethod, - $controller, - $quoteId, - $result, - $exception - ) { - $this->requestMock->expects($this->at(0)) - ->method('getParam') - ->with('payment') - ->will($this->returnValue($paymentMethod)); - - $this->requestMock->expects($this->at(1)) - ->method('getParam') - ->with('controller') - ->will($this->returnValue($controller)); - - $this->quoteMock->expects($this->any()) - ->method('getId') - ->will($this->returnValue($quoteId)); - - $this->cartManagementMock->expects($this->once()) - ->method('placeOrder') - ->willThrowException($exception); - - $this->loggerMock->expects($this->once()) - ->method('critical') - ->with($exception); - - $this->jsonHelperMock->expects($this->any()) - ->method('jsonEncode') - ->with($result); - - $this->placeOrderController->execute(); - } - - /** - * @return array - */ - public function textExecuteDataProvider() - { - $objectSuccess = new \Magento\Framework\DataObject(); - $objectSuccess->setData('success', true); - - return [ - [ - ['method' => null], - IframeConfigProvider::CHECKOUT_IDENTIFIER, - 1, - 1, - ['error_messages' => __('Please choose a payment method.'), 'goto_section' => 'payment'] - ], - [ - ['method' => 'authorizenet_directpost'], - IframeConfigProvider::CHECKOUT_IDENTIFIER, - 1, - 1, - $objectSuccess - ], - ]; - } - - /** - * @return array - */ - public function textExecuteFailedPlaceOrderDataProvider() - { - $objectFailed1 = new \Magento\Framework\DataObject( - [ - 'error' => true, - 'error_messages' => __( - 'A server error stopped your order from being placed. Please try to place your order again.' - ) - ] - ); - $generalException = new \Exception('Exception logging will save the world!'); - $localizedException = new LocalizedException(__('Electronic payments save the trees.')); - $objectFailed2 = new \Magento\Framework\DataObject( - [ - 'error' => true, - 'error_messages' => $localizedException->getMessage() - ] - ); - - return [ - [ - ['method' => 'authorizenet_directpost'], - IframeConfigProvider::CHECKOUT_IDENTIFIER, - 1, - $objectFailed1, - $generalException, - ], - [ - ['method' => 'authorizenet_directpost'], - IframeConfigProvider::CHECKOUT_IDENTIFIER, - 1, - $objectFailed2, - $localizedException, - ], - ]; - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Controller/Directpost/Payment/RedirectTest.php b/app/code/Magento/Authorizenet/Test/Unit/Controller/Directpost/Payment/RedirectTest.php deleted file mode 100644 index 0801d3c020119..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Controller/Directpost/Payment/RedirectTest.php +++ /dev/null @@ -1,89 +0,0 @@ -request = static::getMockForAbstractClass(RequestInterface::class); - - $this->view = static::getMockForAbstractClass(ViewInterface::class); - - $this->coreRegistry = static::getMockBuilder(Registry::class) - ->disableOriginalConstructor() - ->setMethods(['register']) - ->getMock(); - - $this->controller = $objectManager->getObject(Redirect::class, [ - 'request' => $this->request, - 'view' => $this->view, - 'coreRegistry' => $this->coreRegistry - ]); - } - - /** - * @covers \Magento\Authorizenet\Controller\Directpost\Payment\Redirect::execute - */ - public function testExecute() - { - $url = 'http://test.com/redirect?=test'; - $params = [ - 'order_success' => $url - ]; - $this->request->expects(static::once()) - ->method('getParams') - ->willReturn($params); - - $this->coreRegistry->expects(static::once()) - ->method('register') - ->with(Iframe::REGISTRY_KEY, []); - - $this->view->expects(static::once()) - ->method('addPageLayoutHandles'); - $this->view->expects(static::once()) - ->method('loadLayout') - ->with(false) - ->willReturnSelf(); - $this->view->expects(static::once()) - ->method('renderLayout'); - - $this->controller->execute(); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Helper/Backend/DataTest.php b/app/code/Magento/Authorizenet/Test/Unit/Helper/Backend/DataTest.php deleted file mode 100644 index 14ecd7debc972..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Helper/Backend/DataTest.php +++ /dev/null @@ -1,135 +0,0 @@ -urlBuilderMock = $this->createPartialMock(\Magento\Backend\Model\Url::class, ['getUrl']); - - $contextMock = $this->createMock(\Magento\Framework\App\Helper\Context::class); - $contextMock->expects($this->any()) - ->method('getUrlBuilder') - ->willReturn($this->urlBuilderMock); - - $this->orderFactoryMock = $this->createPartialMock(\Magento\Sales\Model\OrderFactory::class, ['create']); - $this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManager::class); - - $this->dataHelper = $helper->getObject( - \Magento\Authorizenet\Helper\Backend\Data::class, - [ - 'context' => $contextMock, - 'storeManager' =>$this->storeManagerMock, - 'orderFactory' =>$this->orderFactoryMock, - 'backendUrl' =>$this->urlBuilderMock - ] - ); - } - - public function testGetPlaceOrderAdminUrl() - { - $this->urlBuilderMock->expects($this->once()) - ->method('getUrl') - ->with('adminhtml/authorizenet_directpost_payment/place') - ->willReturn('some value'); - - $this->assertEquals('some value', $this->dataHelper->getPlaceOrderAdminUrl()); - } - - public function testGetSuccessOrderUrl() - { - $orderMock = $this->createPartialMock( - \Magento\Sales\Model\Order::class, - ['loadByIncrementId', 'getId', '__wakeup'] - ); - $orderMock->expects($this->once()) - ->method('loadByIncrementId') - ->with('invoice number') - ->willReturnSelf(); - - $orderMock->expects($this->once()) - ->method('getId') - ->willReturn('order id'); - - $this->orderFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($orderMock); - - $this->urlBuilderMock->expects($this->once()) - ->method('getUrl') - ->with('sales/order/view', ['order_id' => 'order id']) - ->willReturn('some value'); - - $this->assertEquals( - 'some value', - $this->dataHelper->getSuccessOrderUrl(['x_invoice_num' => 'invoice number', 'some param']) - ); - } - - public function testGetRedirectIframeUrl() - { - $params = ['some params', '_secure' => true]; - $this->urlBuilderMock->expects($this->once()) - ->method('getUrl') - ->with('adminhtml/authorizenet_directpost_payment/redirect', $params) - ->willReturn('some value'); - - $this->assertEquals('some value', $this->dataHelper->getRedirectIframeUrl($params)); - } - - public function testGetRelayUrl() - { - $baseUrl = 'http://base.url/'; - - $defaultStoreMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->getMock(); - - $defaultStoreMock->expects($this->once()) - ->method('getBaseUrl') - ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK) - ->willReturn($baseUrl); - - $this->storeManagerMock->expects($this->once()) - ->method('getDefaultStoreView') - ->willReturn(null); - - $this->storeManagerMock->expects($this->once()) - ->method('getStores') - ->willReturn([$defaultStoreMock]); - - $this->assertSame( - 'http://base.url/authorizenet/directpost_payment/backendResponse', - $this->dataHelper->getRelayUrl() - ); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Helper/DataTest.php b/app/code/Magento/Authorizenet/Test/Unit/Helper/DataTest.php deleted file mode 100644 index 28dd5f866a609..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Helper/DataTest.php +++ /dev/null @@ -1,193 +0,0 @@ -storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->getMockForAbstractClass(); - - $this->dataHelper = $helper->getObject( - \Magento\Authorizenet\Helper\Data::class, - ['storeManager' => $this->storeManagerMock] - ); - } - - /** - * @param $type - * @param $amount - * @param $exception - * @param $additionalMessage - * @param $expected - * @dataProvider getMessagesParamDataProvider - */ - public function testGetTransactionMessage($type, $amount, $exception, $additionalMessage, $expected) - { - $currency = $this->createPartialMock(\Magento\Directory\Model\Currency::class, ['formatTxt', '__wakeup']); - $currency->expects($this->any()) - ->method('formatTxt') - ->will($this->returnValue($amount)); - $order = $this->createPartialMock(\Magento\Sales\Model\Order::class, ['getBaseCurrency', '__wakeup']); - $order->expects($this->any()) - ->method('getBaseCurrency') - ->will($this->returnValue($currency)); - $payment = $this->createPartialMock(\Magento\Payment\Model\Info::class, ['getOrder', '__wakeup']); - $payment->expects($this->any()) - ->method('getOrder') - ->will($this->returnValue($order)); - $card = new \Magento\Framework\DataObject(['cc_last_4' => self::LAST4]); - $message = $this->dataHelper->getTransactionMessage( - $payment, - $type, - self::TRID, - $card, - $amount, - $exception, - $additionalMessage - ); - - $this->assertEquals($expected, $message); - } - - /** - * @return array - */ - public function getMessagesParamDataProvider() - { - $amount = 12.30; - $additionalMessage = 'Addition message.'; - return [ - [ - 'AUTH_ONLY', - $amount, - false, - $additionalMessage, - 'Credit Card: xxxx-' . self::LAST4 . ' amount 12.3 authorize - successful. ' - . 'Authorize.Net Transaction ID ' . self::TRID . '. Addition message.', - ], - [ - 'AUTH_CAPTURE', - $amount, - 'some exception', - false, - 'Credit Card: xxxx-' . self::LAST4 . ' amount 12.3 authorize and capture - failed. ' - . 'Authorize.Net Transaction ID ' . self::TRID . '. some exception' - ], - [ - 'CREDIT', - false, - false, - $additionalMessage, - 'Credit Card: xxxx-' . self::LAST4 . ' refund - successful. ' - . 'Authorize.Net Transaction ID ' . self::TRID . '. Addition message.' - ], - ]; - } - - public function testGetRelayUrl() - { - $storeId = 10; - $baseUrl = 'http://base.url/'; - - $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->getMock(); - - $storeMock->expects($this->once()) - ->method('getBaseUrl') - ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK) - ->willReturn($baseUrl); - - $this->storeManagerMock->expects($this->once()) - ->method('getStore') - ->with($storeId) - ->willReturn($storeMock); - - $this->assertSame( - 'http://base.url/authorizenet/directpost_payment/response', - $this->dataHelper->getRelayUrl($storeId) - ); - } - - /** - * @param string $code - * @param string $expected - * - * @dataProvider getFdsFilterActionLabelDataProvider - */ - public function testGetFdsFilterActionLabel($code, $expected) - { - $this->assertSame($expected, (string)$this->dataHelper->getFdsFilterActionLabel($code)); - } - - /** - * @return array - */ - public function getFdsFilterActionLabelDataProvider() - { - return [ - ['decline ', 'Decline'], - ['hold', 'Hold'], - ['authAndHold', 'Authorize and Hold'], - ['report', 'Report Only'], - ['unknown_status', 'unknown_status'] - ]; - } - - /** - * @param string $code - * @param string $expected - * - * @dataProvider getTransactionStatusLabelDataProvider - */ - public function testGetTransactionStatusLabel($code, $expected) - { - $this->assertSame($expected, (string)$this->dataHelper->getTransactionStatusLabel($code)); - } - - /** - * @return array - */ - public function getTransactionStatusLabelDataProvider() - { - return [ - ['authorizedPendingCapture', 'Authorized/Pending Capture'], - ['capturedPendingSettlement', 'Captured/Pending Settlement'], - ['refundSettledSuccessfully', 'Refund/Settled Successfully'], - ['refundPendingSettlement', 'Refund/Pending Settlement'], - ['declined', 'Declined'], - ['expired', 'Expired'], - ['voided', 'Voided'], - ['FDSPendingReview', 'FDS - Pending Review'], - ['FDSAuthorizedPendingReview', 'FDS - Authorized/Pending Review'], - ['unknown_status', 'unknown_status'] - ]; - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Request/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Request/FactoryTest.php deleted file mode 100644 index 99f2729fcdddf..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Request/FactoryTest.php +++ /dev/null @@ -1,49 +0,0 @@ -requestMock = $this->createMock(\Magento\Authorizenet\Model\Directpost\Request::class); - - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $this->objectManagerMock->expects($this->once()) - ->method('create') - ->with(\Magento\Authorizenet\Model\Directpost\Request::class, []) - ->willReturn($this->requestMock); - - $this->requestFactory = $objectManager->getObject( - \Magento\Authorizenet\Model\Directpost\Request\Factory::class, - ['objectManager' => $this->objectManagerMock] - ); - } - - public function testCreate() - { - $this->assertSame($this->requestMock, $this->requestFactory->create()); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/RequestTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/RequestTest.php deleted file mode 100644 index 94d8f3a0d27a7..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/RequestTest.php +++ /dev/null @@ -1,80 +0,0 @@ -dateTimeFactory = $this->getMockBuilder(DateTimeFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $dateTime = new \DateTime('2016-07-05 00:00:00', new \DateTimeZone('UTC')); - $this->dateTimeFactory->method('create') - ->willReturn($dateTime); - - $this->requestModel = new Request([], $this->dateTimeFactory); - } - - /** - * @param string $signatureKey - * @param string $expectedHash - * @dataProvider signRequestDataProvider - */ - public function testSignRequestData(string $signatureKey, string $expectedHash) - { - /** @var \Magento\Authorizenet\Model\Directpost $paymentMethod */ - $paymentMethod = $this->createMock(\Magento\Authorizenet\Model\Directpost::class); - $paymentMethod->method('getConfigData') - ->willReturnMap( - [ - ['test', null, true], - ['login', null, 'login'], - ['trans_key', null, 'trans_key'], - ['signature_key', null, $signatureKey], - ] - ); - - $this->requestModel->setConstantData($paymentMethod); - $this->requestModel->signRequestData(); - $signHash = $this->requestModel->getXFpHash(); - - $this->assertEquals($expectedHash, $signHash); - } - - /** - * @return array - */ - public function signRequestDataProvider() - { - return [ - [ - 'signatureKey' => '3EAFCE5697C1B4B9748385C1FCD29D86F3B9B41C7EED85A3A01DFF65' . - '70C8C29373C2A153355C3313CDF4AF723C0036DBF244A0821713A910024EE85547CEF37F', - 'expectedHash' => '719ED94DF5CF3510CB5531E8115462C8F12CBCC8E917BD809E8D40B4FF06' . - '1E14953554403DD9813CCCE0F31B184EB4DEF558E9C0747505A0C25420372DB00BE1' - ], - [ - 'signatureKey' => '', - 'expectedHash' => '3656211f2c41d1e4c083606f326c0460' - ], - ]; - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Response/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Response/FactoryTest.php deleted file mode 100644 index bf59a73c14940..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Response/FactoryTest.php +++ /dev/null @@ -1,49 +0,0 @@ -responseMock = $this->createMock(\Magento\Authorizenet\Model\Directpost\Response::class); - - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $this->objectManagerMock->expects($this->once()) - ->method('create') - ->with(\Magento\Authorizenet\Model\Directpost\Response::class, []) - ->willReturn($this->responseMock); - - $this->responseFactory = $objectManager->getObject( - \Magento\Authorizenet\Model\Directpost\Response\Factory::class, - ['objectManager' => $this->objectManagerMock] - ); - } - - public function testCreate() - { - $this->assertSame($this->responseMock, $this->responseFactory->create()); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php deleted file mode 100644 index ff4aa8b5ee361..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php +++ /dev/null @@ -1,128 +0,0 @@ -responseModel = $objectManager->getObject( - \Magento\Authorizenet\Model\Directpost\Response::class - ); - } - - /** - * @param $merchantMd5 - * @param $merchantApiLogin - * @param $amount - * @param $transactionId - * @return string - */ - protected function generateHash($merchantMd5, $merchantApiLogin, $amount, $transactionId) - { - return strtoupper(md5($merchantMd5 . $merchantApiLogin . $transactionId . $amount)); - } - - /** - * @param string $storedHash - * @param string $hashKey - * @param string $merchantApiLogin - * @param float|null $amount - * @param string $transactionId - * @param string $hash - * @param bool $expectedValue - * @dataProvider isValidHashDataProvider - */ - public function testIsValidHash( - string $storedHash, - string $hashKey, - string $merchantApiLogin, - $amount, - string $transactionId, - string $hash, - bool $expectedValue - ) { - $this->responseModel->setXAmount($amount); - $this->responseModel->setXTransId($transactionId); - $this->responseModel->setData($hashKey, $hash); - $result = $this->responseModel->isValidHash($storedHash, $merchantApiLogin); - - $this->assertEquals($expectedValue, $result); - } - - /** - * @return array - */ - public function isValidHashDataProvider() - { - $signatureKey = '3EAFCE5697C1B4B9748385C1FCD29D86F3B9B41C7EED85A3A01DFF6570C8C' . - '29373C2A153355C3313CDF4AF723C0036DBF244A0821713A910024EE85547CEF37F'; - $expectedSha2Hash = '368D48E0CD1274BF41C059138DA69985594021A4AD5B4C5526AE88C8F' . - '7C5769B13C5E1E4358900F3E51076FB69D14B0A797904C22E8A11A52AA49CDE5FBB703C'; - return [ - [ - 'merchantMd5' => 'FCD7F001E9274FDEFB14BFF91C799306', - 'hashKey' => 'x_MD5_Hash', - 'merchantApiLogin' => 'Magento', - 'amount' => null, - 'transactionId' => '1', - 'hash' => '1F24A4EC9A169B2B2A072A5F168E16DC', - 'expectedValue' => true - ], - [ - 'merchantMd5' => '8AEF4E508261A287C3E2F544720FCA3A', - 'hashKey' => 'x_MD5_Hash', - 'merchantApiLogin' => 'Magento2', - 'amount' => 100.50, - 'transactionId' => '2', - 'hash' => '1F24A4EC9A169B2B2A072A5F168E16DC', - 'expectedValue' => false - ], - [ - 'signatureKey' => $signatureKey, - 'hashKey' => 'x_SHA2_Hash', - 'merchantApiLogin' => 'Magento2', - 'amount' => 100.50, - 'transactionId' => '2', - 'hash' => $expectedSha2Hash, - 'expectedValue' => true - ] - ]; - } - - /** - * @param int $xResponseCode - * @param bool $expectedValue - * @dataProvider isApprovedDataProvider - */ - public function testIsApproved($xResponseCode, $expectedValue) - { - $this->responseModel->setXResponseCode($xResponseCode); - $this->assertSame($expectedValue, $this->responseModel->isApproved()); - } - - /** - * @return array - */ - public function isApprovedDataProvider() - { - return [ - [Directpost::RESPONSE_CODE_APPROVED, true], - [Directpost::RESPONSE_CODE_DECLINED, false], - [Directpost::RESPONSE_CODE_ERROR, false], - [Directpost::RESPONSE_CODE_HELD, false], - ]; - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/SessionTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/SessionTest.php deleted file mode 100644 index 35f7a4e15219c..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/SessionTest.php +++ /dev/null @@ -1,58 +0,0 @@ -storageMock = $this - ->getMockBuilder(\Magento\Framework\Session\StorageInterface::class) - ->setMethods(['setQuoteId']) - ->getMockForAbstractClass(); - - $this->objectManager = new ObjectManager($this); - $this->session = $this->objectManager->getObject( - \Magento\Authorizenet\Model\Directpost\Session::class, - [ - 'storage' => $this->storageMock, - ] - ); - } - - public function testSetQuoteId() - { - $quoteId = 1; - - $this->storageMock->expects($this->once()) - ->method('setQuoteId') - ->with($quoteId); - - $this->assertInstanceOf( - \Magento\Authorizenet\Model\Directpost\Session::class, - $this->session->setQuoteId($quoteId) - ); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php deleted file mode 100644 index a1547a0563461..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php +++ /dev/null @@ -1,885 +0,0 @@ -initPaymentMock(); - $this->initResponseFactoryMock(); - $this->initHttpClientMock(); - - $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)->getMock(); - $this->dataHelperMock = $this->getMockBuilder(HelperData::class)->disableOriginalConstructor()->getMock(); - $this->transactionRepositoryMock = $this->getMockBuilder(TransactionRepository::class) - ->disableOriginalConstructor() - ->setMethods(['getByTransactionId']) - ->getMock(); - $this->transactionServiceMock = $this->getMockBuilder(TransactionService::class) - ->disableOriginalConstructor() - ->setMethods(['getTransactionDetails']) - ->getMock(); - $this->paymentFailures = $this->getMockBuilder(PaymentFailuresInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->requestFactory = $this->getMockBuilder(Factory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->httpClientFactoryMock = $this->getMockBuilder(ZendClientFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $helper = new ObjectManagerHelper($this); - $this->directpost = $helper->getObject( - Directpost::class, - [ - 'scopeConfig' => $this->scopeConfigMock, - 'dataHelper' => $this->dataHelperMock, - 'requestFactory' => $this->requestFactory, - 'responseFactory' => $this->responseFactoryMock, - 'transactionRepository' => $this->transactionRepositoryMock, - 'transactionService' => $this->transactionServiceMock, - 'httpClientFactory' => $this->httpClientFactoryMock, - 'paymentFailures' => $this->paymentFailures, - ] - ); - } - - /** - * Create mock for response factory - * - * @return void - */ - private function initResponseFactoryMock() - { - $this->responseFactoryMock = $this->getMockBuilder(ResponseFactory::class) - ->disableOriginalConstructor() - ->getMock(); - $this->responseMock = $this->getMockBuilder(Response::class) - ->setMethods( - [ - 'isValidHash', - 'getXTransId', - 'getXResponseCode', - 'getXResponseReasonCode', - 'getXResponseReasonText', - 'getXAmount', - 'setXResponseCode', - 'setXResponseReasonCode', - 'setXAvsCode', - 'setXResponseReasonText', - 'setXTransId', - 'setXInvoiceNum', - 'setXAmount', - 'setXMethod', - 'setXType', - 'setData', - 'getData', - 'setXAccountNumber', - '__wakeup' - ] - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->responseFactoryMock->expects($this->any())->method('create')->willReturn($this->responseMock); - } - - /** - * Create mock for payment - * - * @return void - */ - private function initPaymentMock() - { - $this->paymentMock = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->setMethods( - [ - 'getOrder', - 'setAmount', - 'setAnetTransType', - 'setXTransId', - 'getId', - 'setAdditionalInformation', - 'getAdditionalInformation', - 'setIsTransactionDenied', - 'setIsTransactionClosed', - 'decrypt', - 'getCcLast4', - 'getParentTransactionId', - 'getPoNumber' - ] - ) - ->getMock(); - } - - /** - * Create a mock for http client - * - * @return void - */ - private function initHttpClientMock() - { - $this->httpClientMock = $this->getMockBuilder(ZendClient::class) - ->disableOriginalConstructor() - ->setMethods(['request', 'getBody', '__wakeup']) - ->getMock(); - } - - public function testGetConfigInterface() - { - $this->assertInstanceOf(ConfigInterface::class, $this->directpost->getConfigInterface()); - } - - public function testGetConfigValue() - { - $field = 'some_field'; - $returnValue = 'expected'; - $this->scopeConfigMock->expects($this->once()) - ->method('getValue') - ->with('payment/authorizenet_directpost/' . $field) - ->willReturn($returnValue); - $this->assertEquals($returnValue, $this->directpost->getValue($field)); - } - - public function testSetDataHelper() - { - $storeId = 'store-id'; - $expectedResult = 'relay-url'; - - $helperDataMock = $this->getMockBuilder(Data::class) - ->disableOriginalConstructor() - ->getMock(); - - $helperDataMock->expects($this->once()) - ->method('getRelayUrl') - ->with($storeId) - ->willReturn($expectedResult); - - $this->directpost->setDataHelper($helperDataMock); - $this->assertEquals($expectedResult, $this->directpost->getRelayUrl($storeId)); - } - - public function testAuthorize() - { - $paymentAction = 'some_action'; - - $this->scopeConfigMock->expects($this->once()) - ->method('getValue') - ->with('payment/authorizenet_directpost/payment_action', 'store', null) - ->willReturn($paymentAction); - $this->paymentMock->expects($this->once()) - ->method('setAdditionalInformation') - ->with('payment_type', $paymentAction); - - $this->directpost->authorize($this->paymentMock, 10); - } - - /** - * @dataProvider dataProviderCaptureWithInvalidAmount - * @expectedExceptionMessage Invalid amount for capture. - * @expectedException \Magento\Framework\Exception\LocalizedException - * - * @param int $invalidAmount - */ - public function testCaptureWithInvalidAmount($invalidAmount) - { - $this->directpost->capture($this->paymentMock, $invalidAmount); - } - - /** - * @return array - */ - public function dataProviderCaptureWithInvalidAmount() - { - return [ - [0], - [0.000], - [-1.000], - [-1], - [null], - ]; - } - - /** - * Test capture has parent transaction id. - * - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCaptureHasParentTransactionId() - { - $amount = 10; - - $this->paymentMock->expects($this->once())->method('setAmount')->with($amount); - $this->paymentMock->expects($this->exactly(2))->method('getParentTransactionId')->willReturn(1); - $this->paymentMock->expects($this->once())->method('setAnetTransType')->willReturn('PRIOR_AUTH_CAPTURE'); - - $this->paymentMock->expects($this->once())->method('getId')->willReturn(1); - $orderMock = $this->getOrderMock(); - $orderMock->expects($this->once())->method('getId')->willReturn(1); - $this->paymentMock->expects($this->once())->method('getOrder')->willReturn($orderMock); - - $transactionMock = $this->getMockBuilder(Transaction::class)->disableOriginalConstructor()->getMock(); - $this->transactionRepositoryMock->expects($this->once()) - ->method('getByTransactionId') - ->with(1, 1, 1) - ->willReturn($transactionMock); - - $this->paymentMock->expects($this->once())->method('setXTransId'); - $this->responseMock->expects($this->once())->method('getData')->willReturn([1]); - - $this->directpost->capture($this->paymentMock, 10); - } - - /** - * @@expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCaptureWithoutParentTransactionId() - { - $amount = 10; - - $this->paymentMock->expects($this->once())->method('setAmount')->with($amount); - $this->paymentMock->expects($this->once())->method('getParentTransactionId')->willReturn(null); - $this->responseMock->expects($this->once())->method('getData')->willReturn([1]); - - $this->directpost->capture($this->paymentMock, 10); - } - - public function testCaptureWithoutParentTransactionIdWithoutData() - { - $amount = 10; - - $this->paymentMock->expects($this->once())->method('setAmount')->with($amount); - $this->paymentMock->expects($this->exactly(2))->method('getParentTransactionId')->willReturn(null); - $this->responseMock->expects($this->once())->method('getData')->willReturn([]); - - $this->paymentMock->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(0) - ->willReturnSelf(); - - $this->httpClientFactoryMock->expects($this->once())->method('create')->willReturn($this->httpClientMock); - $this->httpClientMock->expects($this->once())->method('request')->willReturnSelf(); - - $this->buildRequestTest(); - $this->postRequestTest(); - - $this->directpost->capture($this->paymentMock, 10); - } - - private function buildRequestTest() - { - $orderMock = $this->getOrderMock(); - $orderMock->expects($this->once())->method('getStoreId')->willReturn(1); - $orderMock->expects($this->exactly(2))->method('getIncrementId')->willReturn(self::INVOICE_NUM); - $this->paymentMock->expects($this->once())->method('getOrder')->willReturn($orderMock); - - $this->addRequestMockToRequestFactoryMock(); - } - - private function postRequestTest() - { - $this->httpClientFactoryMock->expects($this->once())->method('create')->willReturn($this->httpClientMock); - $this->httpClientMock->expects($this->once())->method('request')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXResponseCode')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXResponseReasonCode')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXResponseReasonText')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXAvsCode')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXTransId')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXInvoiceNum')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXAmount')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXMethod')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setXType')->willReturnSelf(); - $this->responseMock->expects($this->once())->method('setData')->willReturnSelf(); - - $response = $this->getRefundResponseBody( - Directpost::RESPONSE_CODE_APPROVED, - Directpost::RESPONSE_REASON_CODE_APPROVED, - 'Successful' - ); - $this->httpClientMock->expects($this->once())->method('getBody')->willReturn($response); - $this->responseMock->expects($this->once()) - ->method('getXResponseCode') - ->willReturn(Directpost::RESPONSE_CODE_APPROVED); - $this->responseMock->expects($this->once()) - ->method('getXResponseReasonCode') - ->willReturn(Directpost::RESPONSE_REASON_CODE_APPROVED); - $this->dataHelperMock->expects($this->never())->method('wrapGatewayError'); - } - - public function testGetCgiUrl() - { - $url = 'cgi/url'; - - $this->scopeConfigMock->expects($this->once()) - ->method('getValue') - ->with('payment/authorizenet_directpost/cgi_url', 'store', null) - ->willReturn($url); - - $this->assertEquals($url, $this->directpost->getCgiUrl()); - } - - public function testGetCgiUrlWithEmptyConfigValue() - { - $this->scopeConfigMock->expects($this->once()) - ->method('getValue') - ->with('payment/authorizenet_directpost/cgi_url', 'store', null) - ->willReturn(null); - - $this->assertEquals(Directpost::CGI_URL, $this->directpost->getCgiUrl()); - } - - public function testGetRelayUrl() - { - $storeId = 100; - $url = 'relay/url'; - $this->directpost->setData('store', $storeId); - - $this->dataHelperMock->expects($this->exactly(2)) - ->method('getRelayUrl') - ->with($storeId) - ->willReturn($url); - - $this->assertEquals($url, $this->directpost->getRelayUrl()); - $this->assertEquals($url, $this->directpost->getRelayUrl($storeId)); - } - - public function testGetResponse() - { - $this->assertSame($this->responseMock, $this->directpost->getResponse()); - } - - public function testSetResponseData() - { - $data = [ - 'key' => 'value' - ]; - - $this->responseMock->expects($this->once()) - ->method('setData') - ->with($data) - ->willReturnSelf(); - - $this->assertSame($this->directpost, $this->directpost->setResponseData($data)); - } - - public function testValidateResponseSuccess() - { - $this->prepareTestValidateResponse('some_md5', 'login', true); - $this->assertEquals(true, $this->directpost->validateResponse()); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testValidateResponseFailure() - { - $this->prepareTestValidateResponse('some_md5', 'login', false); - $this->directpost->validateResponse(); - } - - /** - * @param string $transMd5 - * @param string $login - * @param bool $isValidHash - */ - protected function prepareTestValidateResponse($transMd5, $login, $isValidHash) - { - $this->scopeConfigMock->expects($this->exactly(2)) - ->method('getValue') - ->willReturnMap( - [ - ['payment/authorizenet_directpost/trans_md5', 'store', null, $transMd5], - ['payment/authorizenet_directpost/login', 'store', null, $login] - ] - ); - $this->responseMock->expects($this->exactly(1)) - ->method('isValidHash') - ->with($transMd5, $login) - ->willReturn($isValidHash); - } - - public function testCheckTransIdSuccess() - { - $this->responseMock->expects($this->once()) - ->method('getXTransId') - ->willReturn('111'); - - $this->assertEquals(true, $this->directpost->checkTransId()); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCheckTransIdFailure() - { - $this->responseMock->expects($this->once()) - ->method('getXTransId') - ->willReturn(null); - - $this->directpost->checkTransId(); - } - - /** - * @param bool $responseCode - * - * @dataProvider checkResponseCodeSuccessDataProvider - */ - public function testCheckResponseCodeSuccess($responseCode) - { - $this->responseMock->expects($this->once()) - ->method('getXResponseCode') - ->willReturn($responseCode); - - $this->assertEquals(true, $this->directpost->checkResponseCode()); - } - - /** - * @return array - */ - public function checkResponseCodeSuccessDataProvider() - { - return [ - ['responseCode' => Directpost::RESPONSE_CODE_APPROVED], - ['responseCode' => Directpost::RESPONSE_CODE_HELD] - ]; - } - - /** - * Checks response failures behaviour. - * - * @return void - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testCheckResponseCodeFailureDefault() - { - $responseCode = 999999; - $this->responseMock->expects($this->once())->method('getXResponseCode')->willReturn($responseCode); - - $this->directpost->checkResponseCode(); - } - - /** - * Checks response failures behaviour. - * - * @param int $responseCode - * @param int $failuresHandlerCalls - * @return void - * - * @expectedException \Magento\Framework\Exception\LocalizedException - * @dataProvider checkResponseCodeFailureDataProvider - */ - public function testCheckResponseCodeFailureDeclinedOrError(int $responseCode, int $failuresHandlerCalls): void - { - $reasonText = 'reason text'; - - $this->responseMock->expects($this->once()) - ->method('getXResponseCode') - ->willReturn($responseCode); - $this->responseMock->expects($this->once())->method('getXResponseReasonText')->willReturn($reasonText); - $this->dataHelperMock->expects($this->once()) - ->method('wrapGatewayError') - ->with($reasonText) - ->willReturn(__('Gateway error: %1', $reasonText)); - - $this->paymentFailures->expects($this->exactly($failuresHandlerCalls))->method('handle')->with(1); - $orderMock = $this->getOrderMock($failuresHandlerCalls); - - $orderMock->expects($this->exactly($failuresHandlerCalls))->method('getQuoteId')->willReturn(1); - $reflection = new ReflectionClass($this->directpost); - $order = $reflection->getProperty('order'); - $order->setAccessible(true); - $order->setValue($this->directpost, $orderMock); - - $this->directpost->checkResponseCode(); - } - - /** - * @return array - */ - public function checkResponseCodeFailureDataProvider(): array - { - return [ - ['responseCode' => Directpost::RESPONSE_CODE_DECLINED, 1], - ['responseCode' => Directpost::RESPONSE_CODE_ERROR, 1], - ]; - } - - /** - * @param bool $isInitializeNeeded - * - * @dataProvider setIsInitializeNeededDataProvider - */ - public function testSetIsInitializeNeeded($isInitializeNeeded) - { - $this->directpost->setIsInitializeNeeded($isInitializeNeeded); - $this->assertEquals($isInitializeNeeded, $this->directpost->isInitializeNeeded()); - } - - /** - * @return array - */ - public function setIsInitializeNeededDataProvider() - { - return [ - ['isInitializationNeeded' => true], - ['isInitializationNeeded' => false] - ]; - } - - /** - * @param bool $isGatewayActionsLocked - * @param bool $canCapture - * - * @dataProvider canCaptureDataProvider - */ - public function testCanCapture($isGatewayActionsLocked, $canCapture) - { - $this->directpost->setData('info_instance', $this->paymentMock); - - $this->paymentMock->expects($this->once()) - ->method('getAdditionalInformation') - ->with(Directpost::GATEWAY_ACTIONS_LOCKED_STATE_KEY) - ->willReturn($isGatewayActionsLocked); - - $this->assertEquals($canCapture, $this->directpost->canCapture()); - } - - /** - * @return array - */ - public function canCaptureDataProvider() - { - return [ - ['isGatewayActionsLocked' => false, 'canCapture' => true], - ['isGatewayActionsLocked' => true, 'canCapture' => false] - ]; - } - - /** - * @covers \Magento\Authorizenet\Model\Directpost::fetchTransactionInfo - * - * @param $transactionId - * @param $resultStatus - * @param $responseStatus - * @param $responseCode - * @return void - * - * @dataProvider dataProviderTransaction - */ - public function testFetchVoidedTransactionInfo($transactionId, $resultStatus, $responseStatus, $responseCode) - { - $paymentId = 36; - $orderId = 36; - - $this->paymentMock->expects($this->once())->method('getId')->willReturn($paymentId); - - $orderMock = $this->getOrderMock(); - $orderMock->expects($this->once())->method('getId')->willReturn($orderId); - $this->paymentMock->expects($this->once())->method('getOrder')->willReturn($orderMock); - $transactionMock = $this->getMockBuilder(Transaction::class)->disableOriginalConstructor()->getMock(); - $this->transactionRepositoryMock->expects($this->once()) - ->method('getByTransactionId') - ->with($transactionId, $paymentId, $orderId) - ->willReturn($transactionMock); - $document = $this->getTransactionXmlDocument( - $transactionId, - TransactionService::PAYMENT_UPDATE_STATUS_CODE_SUCCESS, - $resultStatus, - $responseStatus, - $responseCode - ); - $this->transactionServiceMock->expects($this->once()) - ->method('getTransactionDetails') - ->with($this->directpost, $transactionId) - ->willReturn($document); - - // transaction should be closed - $this->paymentMock->expects($this->once())->method('setIsTransactionDenied')->with(true); - $this->paymentMock->expects($this->once())->method('setIsTransactionClosed')->with(true); - $transactionMock->expects($this->once())->method('close'); - - $this->directpost->fetchTransactionInfo($this->paymentMock, $transactionId); - } - - /** - * @covers \Magento\Authorizenet\Model\Directpost::refund() - * @return void - */ - public function testSuccessRefund() - { - $card = 1111; - - $this->paymentMock->expects($this->exactly(1))->method('getCcLast4')->willReturn($card); - $this->paymentMock->expects($this->once())->method('decrypt')->willReturn($card); - $this->paymentMock->expects($this->exactly(3)) - ->method('getParentTransactionId') - ->willReturn(self::TRANSACTION_ID . '-capture'); - $this->paymentMock->expects($this->once())->method('getPoNumber')->willReturn(self::INVOICE_NUM); - $this->paymentMock->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(true) - ->willReturnSelf(); - - $this->addRequestMockToRequestFactoryMock(); - - $orderMock = $this->getOrderMock(); - - $orderMock->expects($this->once())->method('getId')->willReturn(1); - $orderMock->expects($this->exactly(2))->method('getIncrementId')->willReturn(self::INVOICE_NUM); - $orderMock->expects($this->once())->method('getStoreId')->willReturn(1); - - $this->paymentMock->expects($this->exactly(2))->method('getOrder')->willReturn($orderMock); - - $transactionMock = $this->getMockBuilder(Transaction::class) - ->disableOriginalConstructor() - ->setMethods(['getAdditionalInformation']) - ->getMock(); - $transactionMock->expects($this->once()) - ->method('getAdditionalInformation') - ->with(Directpost::REAL_TRANSACTION_ID_KEY) - ->willReturn(self::TRANSACTION_ID); - - $this->transactionRepositoryMock->expects($this->once()) - ->method('getByTransactionId') - ->willReturn($transactionMock); - - $this->postRequestTest(); - - $this->directpost->refund($this->paymentMock, self::TOTAL_AMOUNT); - } - - /** - * Get data for tests - * @return array - */ - public function dataProviderTransaction() - { - return [ - [ - 'transactionId' => '9941997799', - 'resultStatus' => 'Successful.', - 'responseStatus' => 'voided', - 'responseCode' => 1 - ] - ]; - } - - /** - * Get transaction data - * @param $transactionId - * @param $resultCode - * @param $resultStatus - * @param $responseStatus - * @param $responseCode - * @return Element - */ - private function getTransactionXmlDocument( - $transactionId, - $resultCode, - $resultStatus, - $responseStatus, - $responseCode - ) { - $body = sprintf( - ' - - - %s - - I00001 - %s - - - - %s - authOnlyTransaction - %s - %s - %s - - ', - $resultCode, - $resultStatus, - $transactionId, - $responseStatus, - $responseCode, - $responseCode - ); - libxml_use_internal_errors(true); - $document = new Element($body); - libxml_use_internal_errors(false); - return $document; - } - - /** - * Get mock for authorize.net request factory - */ - private function addRequestMockToRequestFactoryMock() - { - $request = $this->getMockBuilder(Request::class) - ->disableOriginalConstructor() - ->setMethods(['__wakeup']) - ->getMock(); - $this->requestFactory->expects($this->once()) - ->method('create') - ->willReturn($request); - } - - /** - * Get mock for order - * @return PHPUnit_Framework_MockObject_MockObject - */ - private function getOrderMock() - { - return $this->getMockBuilder(Order::class) - ->disableOriginalConstructor() - ->setMethods( - [ - 'getId', - 'getQuoteId', - 'getIncrementId', - 'getStoreId', - 'getBillingAddress', - 'getShippingAddress', - 'getBaseCurrencyCode', - 'getBaseTaxAmount', - '__wakeup' - ] - ) - ->getMock(); - } - - /** - * Get mocked response for refund transaction - * @param $code - * @param $reasonCode - * @param $reasonText - * @return string - */ - private function getRefundResponseBody($code, $reasonCode, $reasonText) - { - $result = array_fill(0, 50, ''); - $result[0] = $code; // XResponseCode - $result[2] = $reasonCode; // XResponseReasonCode - $result[3] = $reasonText; // XResponseReasonText - $result[6] = self::TRANSACTION_ID; // XTransId - $result[7] = self::INVOICE_NUM; // XInvoiceNum - $result[9] = self::TOTAL_AMOUNT; // XAmount - $result[10] = Directpost::REQUEST_METHOD_CC; // XMethod - $result[11] = Directpost::REQUEST_TYPE_CREDIT; // XType - // @codingStandardsIgnoreStart - $result[37] = md5(self::TRANSACTION_ID); // x_MD5_Hash - // @codingStandardsIgnoreEnd - $result[50] = '48329483921'; // setXAccountNumber - return implode(Directpost::RESPONSE_DELIM_CHAR, $result); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Request/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Request/FactoryTest.php deleted file mode 100644 index 4ac98238f9ed1..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/Request/FactoryTest.php +++ /dev/null @@ -1,49 +0,0 @@ -requestMock = $this->createMock(\Magento\Authorizenet\Model\Request::class); - - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $this->objectManagerMock->expects($this->once()) - ->method('create') - ->with(\Magento\Authorizenet\Model\Request::class, []) - ->willReturn($this->requestMock); - - $this->requestFactory = $objectManager->getObject( - \Magento\Authorizenet\Model\Request\Factory::class, - ['objectManager' => $this->objectManagerMock] - ); - } - - public function testCreate() - { - $this->assertSame($this->requestMock, $this->requestFactory->create()); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Response/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Response/FactoryTest.php deleted file mode 100644 index ddc4f28de8b81..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/Response/FactoryTest.php +++ /dev/null @@ -1,49 +0,0 @@ -responseMock = $this->createMock(\Magento\Authorizenet\Model\Response::class); - - $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class); - $this->objectManagerMock->expects($this->once()) - ->method('create') - ->with(\Magento\Authorizenet\Model\Response::class, []) - ->willReturn($this->responseMock); - - $this->responseFactory = $objectManager->getObject( - \Magento\Authorizenet\Model\Response\Factory::class, - ['objectManager' => $this->objectManagerMock] - ); - } - - public function testCreate() - { - $this->assertSame($this->responseMock, $this->responseFactory->create()); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/TransactionServiceTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/TransactionServiceTest.php deleted file mode 100644 index 092d633648482..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/TransactionServiceTest.php +++ /dev/null @@ -1,167 +0,0 @@ -getHttpClientFactoryMock(); - - $this->authorizenetMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->authorizenetMock->method('getConfigData') - ->willReturnMap([ - ['login', 'test login'], - ['trans_key', 'test key'], - ['cgi_url_td', 'https://apitest.authorize.net/xml/v1/request.api'] - ]); - - $objectManagerHelper = new ObjectManager($this); - $xmlSecurity = $objectManagerHelper->getObject(\Magento\Framework\Xml\Security::class); - $this->transactionService = $objectManagerHelper->getObject( - \Magento\Authorizenet\Model\TransactionService::class, - [ - 'xmlSecurityHelper' => $xmlSecurity, - 'httpClientFactory' => $httpClientFactoryMock - ] - ); - } - - /** - * @covers \Magento\Authorizenet\Model\TransactionService::loadTransactionDetails - * @param $transactionId - * @param $resultStatus - * @param $responseStatus - * @param $responseCode - * @return void - * - * @dataProvider dataProviderTransaction - */ - public function testLoadVoidedTransactionDetails($transactionId, $resultStatus, $responseStatus, $responseCode) - { - $document = $this->getResponseBody( - $transactionId, - TransactionService::PAYMENT_UPDATE_STATUS_CODE_SUCCESS, - $resultStatus, - $responseStatus, - $responseCode - ); - $this->httpClientMock->expects(static::once()) - ->method('getBody') - ->willReturn($document); - - $result = $this->transactionService->getTransactionDetails($this->authorizenetMock, $transactionId); - - static::assertEquals($responseCode, (string)$result->transaction->responseCode); - static::assertEquals($responseCode, (string)$result->transaction->responseReasonCode); - static::assertEquals($responseStatus, (string)$result->transaction->transactionStatus); - } - - /** - * Get data for tests - * @return array - */ - public function dataProviderTransaction() - { - return [ - [ - 'transactionId' => '9941997799', - 'resultStatus' => 'Successful.', - 'responseStatus' => 'voided', - 'responseCode' => 1 - ] - ]; - } - - /** - * Create and return mock for http client factory - * @return \PHPUnit_Framework_MockObject_MockObject - */ - private function getHttpClientFactoryMock() - { - $this->httpClientMock = $this->getMockBuilder(\Magento\Framework\HTTP\ZendClient::class) - ->disableOriginalConstructor() - ->setMethods(['request', 'getBody', '__wakeup']) - ->getMock(); - - $this->httpClientMock->expects(static::once()) - ->method('request') - ->willReturnSelf(); - - $httpClientFactoryMock = $this->getMockBuilder(\Magento\Framework\HTTP\ZendClientFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $httpClientFactoryMock->expects(static::once()) - ->method('create') - ->willReturn($this->httpClientMock); - return $httpClientFactoryMock; - } - - /** - * Get body for xml request - * @param string $transactionId - * @param int $resultCode - * @param string $resultStatus - * @param string $responseStatus - * @param string $responseCode - * @return string - */ - private function getResponseBody($transactionId, $resultCode, $resultStatus, $responseStatus, $responseCode) - { - return sprintf( - ' - - - %s - - I00001 - %s - - - - %s - authOnlyTransaction - %s - %s - %s - - ', - $resultCode, - $resultStatus, - $transactionId, - $responseStatus, - $responseCode, - $responseCode - ); - } -} diff --git a/app/code/Magento/Authorizenet/Test/Unit/Observer/AddFieldsToResponseObserverTest.php b/app/code/Magento/Authorizenet/Test/Unit/Observer/AddFieldsToResponseObserverTest.php deleted file mode 100644 index d59d5eeaa5cae..0000000000000 --- a/app/code/Magento/Authorizenet/Test/Unit/Observer/AddFieldsToResponseObserverTest.php +++ /dev/null @@ -1,237 +0,0 @@ -coreRegistryMock = $this->getMockBuilder(\Magento\Framework\Registry::class) - ->disableOriginalConstructor() - ->getMock(); - $this->paymentMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost::class) - ->disableOriginalConstructor() - ->getMock(); - $this->sessionMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost\Session::class) - ->disableOriginalConstructor() - ->setMethods(['setLastOrderIncrementId', 'addCheckoutOrderIncrementId']) - ->getMock(); - $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $this->actionMock = $this->getMockBuilder(\Magento\Checkout\Controller\Onepage\SaveOrder::class) - ->disableOriginalConstructor() - ->getMock(); - $this->resultMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->addFieldsToResponseObserver = $helper->getObject( - \Magento\Authorizenet\Observer\AddFieldsToResponseObserver::class, - [ - 'coreRegistry' => $this->coreRegistryMock, - 'payment' => $this->paymentMock, - 'session' => $this->sessionMock, - 'storeManager' => $this->storeManagerMock, - ] - ); - } - - /** - * Test for addFieldsToResponse method - * - * @return void - */ - public function testAddFieldsToResponseSuccess() - { - $testData = $this->getAddFieldsToResponseSuccessTestData(); - - $observerMock = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) - ->disableOriginalConstructor() - ->getMock(); - $orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->getMock(); - $orderPaymentMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Payment::class) - ->disableOriginalConstructor() - ->getMock(); - $instanceMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost::class) - ->disableOriginalConstructor() - ->getMock(); - $requestToAuthorizenetMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost\Request::class) - ->disableOriginalConstructor() - ->setMethods(['setControllerActionName', 'setIsSecure', 'getData']) - ->getMock(); - $requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class) - ->disableOriginalConstructor() - ->setMethods(['getControllerName']) - ->getMockForAbstractClass(); - $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->coreRegistryMock->expects($this->once()) - ->method('registry') - ->with('directpost_order') - ->willReturn($orderMock); - $orderMock->expects($this->once()) - ->method('getId') - ->willReturn($testData['order.getId']); - $orderMock->expects($this->once()) - ->method('getPayment') - ->willReturn($orderPaymentMock); - $orderPaymentMock->expects($this->once()) - ->method('getMethod') - ->willReturn($testData['orderPayment.getMethod']); - $this->paymentMock->expects($this->exactly(2)) - ->method('getCode') - ->willReturn($testData['payment.getCode']); - $observerMock->expects($this->atLeastOnce()) - ->method('getData') - ->willReturnMap($testData['observer.getData']); - $this->resultMock->expects($this->once()) - ->method('getData') - ->willReturn($testData['result.getData']); - $orderMock->expects($this->atLeastOnce()) - ->method('getIncrementId') - ->willReturn($testData['order.getIncrementId']); - $this->sessionMock->expects($this->once()) - ->method('addCheckoutOrderIncrementId') - ->with($testData['session.addCheckoutOrderIncrementId']); - $this->sessionMock->expects($this->once()) - ->method('setLastOrderIncrementId') - ->with($testData['session.setLastOrderIncrementId']); - $orderPaymentMock->expects($this->once()) - ->method('getMethodInstance') - ->willReturn($instanceMock); - $instanceMock->expects($this->once()) - ->method('generateRequestFromOrder') - ->with($orderMock) - ->willReturn($requestToAuthorizenetMock); - $this->actionMock->expects($this->once()) - ->method('getRequest') - ->willReturn($requestMock); - $requestMock->expects($this->once()) - ->method('getControllerName') - ->willReturn($testData['request.getControllerName']); - $requestToAuthorizenetMock->expects($this->once()) - ->method('setControllerActionName') - ->with($testData['requestToAuthorizenet.setControllerActionName']); - $this->storeManagerMock->expects($this->once()) - ->method('getStore') - ->willReturn($storeMock); - $storeMock->expects($this->once()) - ->method('isCurrentlySecure') - ->willReturn($testData['store.isCurrentlySecure']); - $requestToAuthorizenetMock->expects($this->once()) - ->method('setIsSecure') - ->with($testData['requestToAuthorizenet.setIsSecure']); - $requestToAuthorizenetMock->expects($this->once()) - ->method('getData') - ->willReturn($testData['requestToAuthorizenet.getData']); - $this->resultMock->expects($this->once()) - ->method('setData') - ->with($testData['result.setData']); - - $this->addFieldsToResponseObserver->execute($observerMock); - } - - /** - * Get data for test testAddFieldsToResponseSuccess - * - * @return array - */ - protected function getAddFieldsToResponseSuccessTestData() - { - $requestFields = [ - 'field-1' => 'field-value-1', - 'field-2' => 'field-value-2', - 'field-3' => 'field-value-3', - ]; - $secure = 'test-currently-secure'; - $controllerName = 'test-controller-name'; - $incrementId = '0000000001'; - $paymentCode = 'test-payment-code'; - - return [ - 'order.getId' => 77, - 'orderPayment.getMethod' => $paymentCode, - 'payment.getCode' => $paymentCode, - 'observer.getData' => [ - ['action', null, $this->actionMock], - ['result', null, $this->resultMock], - ], - 'result.getData' => [ - 'error' => false - ], - 'order.getIncrementId' => $incrementId, - 'session.addCheckoutOrderIncrementId' => $incrementId, - 'session.setLastOrderIncrementId' => $incrementId, - 'request.getControllerName' => $controllerName, - 'requestToAuthorizenet.setControllerActionName' => $controllerName, - 'store.isCurrentlySecure' => $secure, - 'requestToAuthorizenet.setIsSecure' => $secure, - 'requestToAuthorizenet.getData' => $requestFields, - 'result.setData' => [ - 'error' => false, - 'test-payment-code' => [ - 'fields' => $requestFields - ] - ] - ]; - } -} diff --git a/app/code/Magento/Authorizenet/composer.json b/app/code/Magento/Authorizenet/composer.json deleted file mode 100644 index 9dcbc7ec7dfb3..0000000000000 --- a/app/code/Magento/Authorizenet/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "magento/module-authorizenet", - "description": "N/A", - "config": { - "sort-packages": true - }, - "require": { - "php": "~7.1.3||~7.2.0||~7.3.0", - "magento/framework": "*", - "magento/module-backend": "*", - "magento/module-catalog": "*", - "magento/module-checkout": "*", - "magento/module-payment": "*", - "magento/module-quote": "*", - "magento/module-sales": "*", - "magento/module-store": "*" - }, - "suggest": { - "magento/module-config": "*" - }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "autoload": { - "files": [ - "registration.php" - ], - "psr-4": { - "Magento\\Authorizenet\\": "" - } - } -} diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/di.xml b/app/code/Magento/Authorizenet/etc/adminhtml/di.xml deleted file mode 100644 index 9305ac521c50a..0000000000000 --- a/app/code/Magento/Authorizenet/etc/adminhtml/di.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - Magento\Backend\Model\Session\Quote - - Magento\Payment\Block\Adminhtml\Transparent\Form - - - - - - Magento\Backend\Model\Session\Quote - - - diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/events.xml b/app/code/Magento/Authorizenet/etc/adminhtml/events.xml deleted file mode 100644 index 085598d3fa95c..0000000000000 --- a/app/code/Magento/Authorizenet/etc/adminhtml/events.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/routes.xml b/app/code/Magento/Authorizenet/etc/adminhtml/routes.xml deleted file mode 100644 index 00bb0475766f9..0000000000000 --- a/app/code/Magento/Authorizenet/etc/adminhtml/routes.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/system.xml b/app/code/Magento/Authorizenet/etc/adminhtml/system.xml deleted file mode 100644 index fe91967ed4a62..0000000000000 --- a/app/code/Magento/Authorizenet/etc/adminhtml/system.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - -
- - - - - Magento\Config\Model\Config\Source\Yesno - - - - Magento\Authorizenet\Model\Source\PaymentAction - - - - - - - Magento\Config\Model\Config\Backend\Encrypted - - - - Magento\Config\Model\Config\Backend\Encrypted - - - - Magento\Config\Model\Config\Backend\Encrypted - - - - Magento\Config\Model\Config\Backend\Encrypted - - - - Magento\Sales\Model\Config\Source\Order\Status\Processing - - - - Magento\Config\Model\Config\Source\Yesno - - - - - - - - - - Magento\Config\Model\Config\Source\Locale\Currency - - - - Magento\Config\Model\Config\Source\Yesno - - - - Magento\Config\Model\Config\Source\Yesno - - - - validate-email - - - - Magento\Authorizenet\Model\Source\Cctype - - - - Magento\Config\Model\Config\Source\Yesno - - - - Magento\Payment\Model\Config\Source\Allspecificcountries - - - - Magento\Directory\Model\Config\Source\Country - - - - validate-number validate-zero-or-greater - - - - validate-number validate-zero-or-greater - - - - validate-number - - -
-
-
diff --git a/app/code/Magento/Authorizenet/etc/config.xml b/app/code/Magento/Authorizenet/etc/config.xml deleted file mode 100644 index 60356460f553f..0000000000000 --- a/app/code/Magento/Authorizenet/etc/config.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - 0 - AE,VI,MC,DI,JCB,DN - 0 - 0 - - - Magento\Authorizenet\Model\Directpost - processing - authorize - 1 - Credit Card Direct Post (Authorize.Net) - - - - 0 - USD - 1 - / - x_card_code,x_exp_date,x_card_num - authorizenet/directpost_payment/place - https://test.authorize.net/gateway/transact.dll - https://secure.authorize.net/gateway/transact.dll - https://apitest.authorize.net/xml/v1/request.api - https://api2.authorize.net/xml/v1/request.api - x_card_type,x_account_number,x_avs_code,x_auth_code,x_response_reason_text,x_cvv2_resp_code - authorizenet - - - - diff --git a/app/code/Magento/Authorizenet/etc/di.xml b/app/code/Magento/Authorizenet/etc/di.xml deleted file mode 100644 index 69d24019f2fb7..0000000000000 --- a/app/code/Magento/Authorizenet/etc/di.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - authorizenet_directpost - - - - - Magento\Authorizenet\Model\Directpost\Session\Storage - - - - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 1 - 1 - 1 - 1 - - - - - - Magento\Authorizenet\Model\Directpost - - - diff --git a/app/code/Magento/Authorizenet/etc/frontend/di.xml b/app/code/Magento/Authorizenet/etc/frontend/di.xml deleted file mode 100644 index a0e5d907b15aa..0000000000000 --- a/app/code/Magento/Authorizenet/etc/frontend/di.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - Magento\Checkout\Model\Session - - - - - - /authorizenet/ - - - - - - Magento\Checkout\Model\Session - - - - - - Magento\Authorizenet\Model\Directpost::METHOD_CODE - - - - - - Magento\Authorizenet\Model\Directpost::METHOD_CODE - - - - - - DirectpostIframeCcConfigProvider - - - - diff --git a/app/code/Magento/Authorizenet/etc/frontend/events.xml b/app/code/Magento/Authorizenet/etc/frontend/events.xml deleted file mode 100644 index 9910dc4776fbe..0000000000000 --- a/app/code/Magento/Authorizenet/etc/frontend/events.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - diff --git a/app/code/Magento/Authorizenet/etc/frontend/page_types.xml b/app/code/Magento/Authorizenet/etc/frontend/page_types.xml deleted file mode 100644 index 56bfca71231cd..0000000000000 --- a/app/code/Magento/Authorizenet/etc/frontend/page_types.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/app/code/Magento/Authorizenet/etc/frontend/routes.xml b/app/code/Magento/Authorizenet/etc/frontend/routes.xml deleted file mode 100644 index e570f24f66c9c..0000000000000 --- a/app/code/Magento/Authorizenet/etc/frontend/routes.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - diff --git a/app/code/Magento/Authorizenet/etc/frontend/sections.xml b/app/code/Magento/Authorizenet/etc/frontend/sections.xml deleted file mode 100644 index 1239398b06a10..0000000000000 --- a/app/code/Magento/Authorizenet/etc/frontend/sections.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - -
-
- - diff --git a/app/code/Magento/Authorizenet/etc/payment.xml b/app/code/Magento/Authorizenet/etc/payment.xml deleted file mode 100644 index 1d2cac374d8dc..0000000000000 --- a/app/code/Magento/Authorizenet/etc/payment.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - diff --git a/app/code/Magento/Authorizenet/i18n/en_US.csv b/app/code/Magento/Authorizenet/i18n/en_US.csv deleted file mode 100644 index d724bd960d310..0000000000000 --- a/app/code/Magento/Authorizenet/i18n/en_US.csv +++ /dev/null @@ -1,75 +0,0 @@ -"You created the order.","You created the order." -"Order saving error: %1","Order saving error: %1" -"Please choose a payment method.","Please choose a payment method." -"We can't process your order right now. Please try again later.","We can't process your order right now. Please try again later." -"An error occurred on the server. Please try to place the order again.","An error occurred on the server. Please try to place the order again." -"Credit Card: xxxx-%1","Credit Card: xxxx-%1" -"amount %1","amount %1" -failed.,failed. -successful.,successful. -"Authorize.Net Transaction ID %1.","Authorize.Net Transaction ID %1." -authorize,authorize -"authorize and capture","authorize and capture" -capture,capture -refund,refund -void,void -"Gateway error: %1","Gateway error: %1" -"Something went wrong in the payment gateway.","Something went wrong in the payment gateway." -"Invalid amount for capture.","Invalid amount for capture." -"Payment capturing error.","Payment capturing error." -"Invalid transaction ID.","Invalid transaction ID." -"Payment voiding error.","Payment voiding error." -"Invalid amount for refund.","Invalid amount for refund." -"Payment refunding error.","Payment refunding error." -"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed." -"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order." -"There was a payment authorization error.","There was a payment authorization error." -"Please enter a transaction ID to authorize this payment.","Please enter a transaction ID to authorize this payment." -"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again." -"Transaction %1 has been approved. Amount %2. Transaction status is ""%3""","Transaction %1 has been approved. Amount %2. Transaction status is ""%3""" -"Transaction %1 has been voided/declined. Transaction status is ""%2"". Amount %3.","Transaction %1 has been voided/declined. Transaction status is ""%2"". Amount %3." -"Authorize Only","Authorize Only" -"Authorize and Capture","Authorize and Capture" -"Unable to get transaction details. Try again later.","Unable to get transaction details. Try again later." -"Electronic payments save the trees.","Electronic payments save the trees." -"Credit Card Type","Credit Card Type" -"Please Select","Please Select" -"Credit Card Number","Credit Card Number" -"Expiration Date","Expiration Date" -"Card Verification Number","Card Verification Number" -"Fraud Detection ","Fraud Detection " -"FDS Filter Action","FDS Filter Action" -"AVS Response","AVS Response" -"Card Code Response","Card Code Response" -"CAVV Response","CAVV Response" -"Fraud Filters","Fraud Filters" -"Place Order","Place Order" -"Sorry, but something went wrong. Please contact the seller.","Sorry, but something went wrong. Please contact the seller." -"Authorize.Net Direct Post (Deprecated)","Authorize.Net Direct Post (Deprecated)" -Enabled,Enabled -"Payment Action","Payment Action" -Title,Title -"API Login ID","API Login ID" -"Transaction Key","Transaction Key" -"Merchant MD5","Merchant MD5" -"New Order Status","New Order Status" -"Test Mode","Test Mode" -"Gateway URL","Gateway URL" -"Transaction Details URL","Transaction Details URL" -"Accepted Currency","Accepted Currency" -Debug,Debug -"Email Customer","Email Customer" -"Merchant's Email","Merchant's Email" -"Credit Card Types","Credit Card Types" -"Credit Card Verification","Credit Card Verification" -"Payment from Applicable Countries","Payment from Applicable Countries" -"Payment from Specific Countries","Payment from Specific Countries" -"Minimum Order Total","Minimum Order Total" -"Maximum Order Total","Maximum Order Total" -"Sort Order","Sort Order" -"x_card_type","Credit Card Type" -"x_account_number", "Credit Card Number" -"x_avs_code","AVS Response Code" -"x_auth_code","Processor Authentication Code" -"x_response_reason_text","Processor Response Text" -"x_cvv2_resp_code","CVV2 Response Code" diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/adminhtml_authorizenet_directpost_payment_redirect.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/adminhtml_authorizenet_directpost_payment_redirect.xml deleted file mode 100644 index e11cdf8843497..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/layout/adminhtml_authorizenet_directpost_payment_redirect.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_index.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_index.xml deleted file mode 100644 index b675e49d72618..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_index.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - authorizenet_directpost - Magento_Authorizenet::directpost/info.phtml - - - - diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml deleted file mode 100644 index ae14700836667..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - authorizenet_directpost - Magento_Authorizenet::directpost/info.phtml - - - - diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_view.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_view.xml deleted file mode 100644 index 57aeffce62c27..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_view.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/iframe.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/iframe.phtml deleted file mode 100644 index 3088713989453..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/iframe.phtml +++ /dev/null @@ -1,31 +0,0 @@ -getParams(); -$helper = $block->getHelper('adminhtml'); -?> - - - - - - diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml deleted file mode 100644 index bec87738a83c1..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml +++ /dev/null @@ -1,152 +0,0 @@ -escapeHtml($block->getMethodCode()); -$method = $block->getMethod(); -$controller = $block->escapeHtml($block->getRequest()->getControllerName()); -$orderUrl = $block->escapeUrl($block->getHelper('adminhtml')->getPlaceOrderAdminUrl()); -$ccType = $block->getInfoData('cc_type'); -$ccExpMonth = $block->getInfoData('cc_exp_month'); -$ccExpYear = $block->getInfoData('cc_exp_year'); -?> - - - - - - diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml deleted file mode 100644 index 15325e15de1e1..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml +++ /dev/null @@ -1,56 +0,0 @@ -getPayment(); -$fraudDetails = $payment->getAdditionalInformation('fraud_details'); -?> - - -
- escapeHtml(__('Fraud Detection ')) ?> -
- -
-
- - escapeHtml(__('FDS Filter Action')) ?>: - escapeHtml($fraudDetails['fds_filter_action']) ?> -
- - - - escapeHtml(__('AVS Response')) ?>: - escapeHtml($fraudDetails['avs_response']) ?> -
- - - - escapeHtml(__('Card Code Response')) ?>: - escapeHtml($fraudDetails['card_code_response']) ?> -
- - - - escapeHtml(__('CAVV Response')) ?>: - escapeHtml($fraudDetails['cavv_response']) ?> -
- - - - escapeHtml(__('Fraud Filters')) ?>: -
- - escapeHtml($filter['name']) ?>: - escapeHtml($filter['action']) ?> -
- - -
-
- diff --git a/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js b/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js deleted file mode 100644 index eb162034bc04d..0000000000000 --- a/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js +++ /dev/null @@ -1,345 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery', - 'mage/backend/validation', - 'prototype' -], function (jQuery) { - window.directPost = Class.create(); - directPost.prototype = { - initialize: function (methodCode, iframeId, controller, orderSaveUrl, cgiUrl, nativeAction) { - var prepare = function (event, method) { - if (method === 'authorizenet_directpost') { - this.preparePayment(); - } else { - jQuery('#edit_form') - .off('submitOrder.authorizenet'); - } - }; - - this.iframeId = iframeId; - this.controller = controller; - this.orderSaveUrl = orderSaveUrl; - this.nativeAction = nativeAction; - this.cgiUrl = cgiUrl; - this.code = methodCode; - this.inputs = ['cc_type', 'cc_number', 'expiration', 'expiration_yr', 'cc_cid']; - this.headers = []; - this.isValid = true; - this.paymentRequestSent = false; - this.orderIncrementId = false; - this.successUrl = false; - this.hasError = false; - this.tmpForm = false; - - this.onLoadIframe = this.loadIframe.bindAsEventListener(this); - this.onLoadOrderIframe = this.loadOrderIframe.bindAsEventListener(this); - this.onSubmitAdminOrder = this.submitAdminOrder.bindAsEventListener(this); - - jQuery('#edit_form').on('changePaymentMethod', prepare.bind(this)); - - jQuery('#edit_form').trigger( - 'changePaymentMethod', - [ - jQuery('#edit_form').find(':radio[name="payment[method]"]:checked').val() - ] - ); - }, - - validate: function () { - this.isValid = true; - this.inputs.each(function (elemIndex) { - if ($(this.code + '_' + elemIndex)) { - if (!jQuery.validator.validateElement($(this.code + '_' + elemIndex))) { - this.isValid = false; - } - } - }, this); - - return this.isValid; - }, - - changeInputOptions: function (param, value) { - this.inputs.each(function (elemIndex) { - if ($(this.code + '_' + elemIndex)) { - $(this.code + '_' + elemIndex).writeAttribute(param, value); - } - }, this); - }, - - preparePayment: function () { - this.changeInputOptions('autocomplete', 'off'); - jQuery('#edit_form') - .off('submitOrder') - .on('submitOrder.authorizenet', this.submitAdminOrder.bind(this)); - - if ($(this.iframeId)) { - // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality - jQuery('.scalable.save:not(disabled)').removeAttr('onclick'); - jQuery(document).off('click.directPost'); - jQuery(document).on( - 'click.directPost', - '.scalable.save:not(disabled)', - jQuery.proxy(this.onSubmitAdminOrder, this) - ); - $('order-' + this.iframeId).observe('load', this.onLoadOrderIframe); - $(this.iframeId).observe('load', this.onLoadIframe); - } - }, - - loadIframe: function () { - if (this.paymentRequestSent) { - if (!this.orderRequestSent) { - this.paymentRequestSent = false; - - if (!this.hasError) { - this.returnQuote(); - } else { - this.changeInputOptions('disabled', false); - jQuery('body').trigger('processStop'); - enableElements('save'); - } - } - - if (this.tmpForm) { - document.body.removeChild(this.tmpForm); - } - } - }, - - loadOrderIframe: function () { - if (this.orderRequestSent) { - $(this.iframeId).hide(); - var data = $('order-' + this.iframeId).contentWindow.document.body.getElementsByTagName('pre')[0].innerHTML; - - this.saveAdminOrderSuccess(data); - this.orderRequestSent = false; - } - }, - - showError: function (msg) { - this.hasError = true; - - if (this.controller == 'onepage') { - $(this.iframeId).hide(); - this.resetLoadWaiting(); - } - alert(msg); - }, - - returnQuote: function () { - var url = this.orderSaveUrl.replace('place', 'returnQuote'); - - new Ajax.Request(url, { - onSuccess: function (transport) { - try { - response = transport.responseText.evalJSON(true); - } catch (e) { - response = {}; - } - - if (response.error_message) { - alert(response.error_message); - } - $(this.iframeId).show(); - this.changeInputOptions('disabled', false); - jQuery('body').trigger('processStop'); - enableElements('save'); - }.bind(this) - }); - }, - - setLoadWaiting: function () { - this.headers.each(function (header) { - header.removeClassName('allow'); - }); - checkout.setLoadWaiting('review'); - }, - - resetLoadWaiting: function () { - this.headers.each(function (header) { - header.addClassName('allow'); - }); - checkout.setLoadWaiting(false); - }, - - submitAdminOrder: function () { - // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality - var editForm = jQuery('#edit_form'); - - if (editForm.valid()) { - // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality - paymentMethodEl = editForm.find(':radio[name="payment[method]"]:checked'); - this.hasError = false; - - if (paymentMethodEl.val() == this.code) { - jQuery('body').trigger('processStart'); - setLoaderPosition(); - this.changeInputOptions('disabled', 'disabled'); - this.paymentRequestSent = true; - this.orderRequestSent = true; - // Temporary solutions will be removed after refactoring Authorize.Net (sales) functionality - editForm.attr('action', this.orderSaveUrl); - editForm.attr('target', - jQuery('#order-' + this.iframeId).attr('name')); - editForm.append(this.createHiddenElement('controller', this.controller)); - disableElements('save'); - // Temporary solutions will be removed after refactoring Authorize.Net (sales) functionality - order._realSubmit(); - } else { - editForm.attr('action', this.nativeAction); - editForm.attr('target', '_top'); - disableElements('save'); - // Temporary solutions will be removed after refactoring Authorize.Net (sales) functionality - order._realSubmit(); - } - } - }, - - recollectQuote: function () { - var area = ['sidebar', 'items', 'shipping_method', 'billing_method', 'totals', 'giftmessage']; - - area = order.prepareArea(area); - var url = order.loadBaseUrl + 'block/' + area; - var info = $('order-items_grid').select('input', 'select', 'textarea'); - var data = {}; - - for (var i = 0; i < info.length; i++) { - if (!info[i].disabled && (info[i].type != 'checkbox' || info[i].checked)) { - data[info[i].name] = info[i].getValue(); - } - } - data.reset_shipping = true; - data.update_items = true; - - if ($('coupons:code') && $F('coupons:code')) { - data['order[coupon][code]'] = $F('coupons:code'); - } - data.json = true; - new Ajax.Request(url, { - parameters: data, - loaderArea: 'html-body', - onSuccess: function (transport) { - jQuery('#edit_form').submit(); - } - }); - - }, - - saveAdminOrderSuccess: function (data) { - try { - response = data.evalJSON(true); - } catch (e) { - response = {}; - } - - if (response.directpost) { - this.orderIncrementId = response.directpost.fields.x_invoice_num; - var paymentData = {}; - - for (var key in response.directpost.fields) { - paymentData[key] = response.directpost.fields[key]; - } - var preparedData = this.preparePaymentRequest(paymentData); - - this.sendPaymentRequest(preparedData); - } else { - if (response.redirect) { - window.location = response.redirect; - } - - if (response.error_messages) { - var msg = response.error_messages; - - if (typeof msg == 'object') { - msg = msg.join('\n'); - } - - if (msg) { - alert(msg); - } - } - } - }, - - preparePaymentRequest: function (data) { - if ($(this.code + '_cc_cid')) { - data.x_card_code = $(this.code + '_cc_cid').value; - } - var year = $(this.code + '_expiration_yr').value; - - if (year.length > 2) { - year = year.substring(2); - } - var month = parseInt($(this.code + '_expiration').value, 10); - - if (month < 10) { - month = '0' + month; - } - - data.x_exp_date = month + '/' + year; - data.x_card_num = $(this.code + '_cc_number').value; - - return data; - }, - - sendPaymentRequest: function (preparedData) { - this.recreateIframe(); - this.tmpForm = document.createElement('form'); - this.tmpForm.style.display = 'none'; - this.tmpForm.enctype = 'application/x-www-form-urlencoded'; - this.tmpForm.method = 'POST'; - document.body.appendChild(this.tmpForm); - this.tmpForm.action = this.cgiUrl; - this.tmpForm.target = $(this.iframeId).readAttribute('name'); - this.tmpForm.setAttribute('target', $(this.iframeId).readAttribute('name')); - - for (var param in preparedData) { - this.tmpForm.appendChild(this.createHiddenElement(param, preparedData[param])); - } - - this.paymentRequestSent = true; - this.tmpForm.submit(); - }, - - createHiddenElement: function (name, value) { - var field; - - if (isIE) { - field = document.createElement('input'); - field.setAttribute('type', 'hidden'); - field.setAttribute('name', name); - field.setAttribute('value', value); - } else { - field = document.createElement('input'); - field.type = 'hidden'; - field.name = name; - field.value = value; - } - - return field; - }, - - recreateIframe: function () { - if ($(this.iframeId)) { - var nextElement = $(this.iframeId).next(); - var src = $(this.iframeId).readAttribute('src'); - var name = $(this.iframeId).readAttribute('name'); - - $(this.iframeId).stopObserving(); - $(this.iframeId).remove(); - var iframe = ' -
- -
-
- - - -
- -
-
- -
-
- - diff --git a/app/code/Magento/AuthorizenetAcceptjs/Block/Form.php b/app/code/Magento/AuthorizenetAcceptjs/Block/Form.php deleted file mode 100644 index f669ead967c59..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Block/Form.php +++ /dev/null @@ -1,64 +0,0 @@ -config = $config; - $this->sessionQuote = $sessionQuote; - } - - /** - * Check if cvv validation is available - * - * @return boolean - */ - public function isCvvEnabled(): bool - { - return $this->config->isCvvEnabled($this->sessionQuote->getStoreId()); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Block/Info.php b/app/code/Magento/AuthorizenetAcceptjs/Block/Info.php deleted file mode 100644 index 1876685998643..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Block/Info.php +++ /dev/null @@ -1,33 +0,0 @@ -config = $config; - $this->json = $json; - } - - /** - * Retrieves the config that should be used by the block - * - * @return string - */ - public function getPaymentConfig(): string - { - $payment = $this->config->getConfig()['payment']; - $config = $payment[$this->getMethodCode()]; - $config['code'] = $this->getMethodCode(); - - return $this->json->serialize($config); - } - - /** - * Returns the method code for this payment method - * - * @return string - */ - public function getMethodCode(): string - { - return Config::METHOD; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/AcceptPaymentStrategyCommand.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/AcceptPaymentStrategyCommand.php deleted file mode 100644 index d59edde212760..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/AcceptPaymentStrategyCommand.php +++ /dev/null @@ -1,77 +0,0 @@ -commandPool = $commandPool; - $this->subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function execute(array $commandSubject): void - { - if ($this->shouldAcceptInGateway($commandSubject)) { - $this->commandPool->get(self::ACCEPT_FDS) - ->execute($commandSubject); - } - } - - /** - * Determines if the transaction needs to be accepted in the gateway - * - * @param array $commandSubject - * @return bool - * @throws CommandException - */ - private function shouldAcceptInGateway(array $commandSubject): bool - { - $details = $this->commandPool->get('get_transaction_details') - ->execute($commandSubject) - ->get(); - - return in_array($details['transaction']['transactionStatus'], self::NEEDS_APPROVAL_STATUSES); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/CaptureStrategyCommand.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/CaptureStrategyCommand.php deleted file mode 100644 index 4318441014ad7..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/CaptureStrategyCommand.php +++ /dev/null @@ -1,143 +0,0 @@ -commandPool = $commandPool; - $this->transactionRepository = $repository; - $this->filterBuilder = $filterBuilder; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function execute(array $commandSubject): void - { - /** @var PaymentDataObjectInterface $paymentDO */ - $paymentDO = $this->subjectReader->readPayment($commandSubject); - - $command = $this->getCommand($paymentDO); - $this->commandPool->get($command) - ->execute($commandSubject); - } - - /** - * Get execution command name. - * - * @param PaymentDataObjectInterface $paymentDO - * @return string - */ - private function getCommand(PaymentDataObjectInterface $paymentDO): string - { - $payment = $paymentDO->getPayment(); - ContextHelper::assertOrderPayment($payment); - - // If auth transaction does not exist then execute authorize&capture command - $captureExists = $this->captureTransactionExists($payment); - if (!$payment->getAuthorizationTransaction() && !$captureExists) { - return self::SALE; - } - - return self::CAPTURE; - } - - /** - * Check if capture transaction already exists - * - * @param OrderPaymentInterface $payment - * @return bool - */ - private function captureTransactionExists(OrderPaymentInterface $payment): bool - { - $this->searchCriteriaBuilder->addFilters( - [ - $this->filterBuilder - ->setField('payment_id') - ->setValue($payment->getId()) - ->create(), - ] - ); - - $this->searchCriteriaBuilder->addFilters( - [ - $this->filterBuilder - ->setField('txn_type') - ->setValue(TransactionInterface::TYPE_CAPTURE) - ->create(), - ] - ); - - $searchCriteria = $this->searchCriteriaBuilder->create(); - $count = $this->transactionRepository->getList($searchCriteria) - ->getTotalCount(); - - return $count > 0; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/FetchTransactionInfoCommand.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/FetchTransactionInfoCommand.php deleted file mode 100644 index d0c1ceac81378..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/FetchTransactionInfoCommand.php +++ /dev/null @@ -1,90 +0,0 @@ -commandPool = $commandPool; - $this->subjectReader = $subjectReader; - $this->config = $config; - $this->handler = $handler; - } - - /** - * @inheritdoc - */ - public function execute(array $commandSubject): array - { - $paymentDO = $this->subjectReader->readPayment($commandSubject); - $order = $paymentDO->getOrder(); - - $command = $this->commandPool->get('get_transaction_details'); - $result = $command->execute($commandSubject); - $response = $result->get(); - - if ($this->handler) { - $this->handler->handle($commandSubject, $response); - } - - $additionalInformationKeys = $this->config->getTransactionInfoSyncKeys($order->getStoreId()); - $rawDetails = []; - foreach ($additionalInformationKeys as $key) { - if (isset($response['transaction'][$key])) { - $rawDetails[$key] = $response['transaction'][$key]; - } - } - - return $rawDetails; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/GatewayQueryCommand.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/GatewayQueryCommand.php deleted file mode 100644 index 7185639936fa4..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/GatewayQueryCommand.php +++ /dev/null @@ -1,103 +0,0 @@ -requestBuilder = $requestBuilder; - $this->transferFactory = $transferFactory; - $this->client = $client; - $this->validator = $validator; - $this->logger = $logger; - } - - /** - * @inheritdoc - * - * @throws Exception - */ - public function execute(array $commandSubject): ResultInterface - { - $transferO = $this->transferFactory->create( - $this->requestBuilder->build($commandSubject) - ); - - try { - $response = $this->client->placeRequest($transferO); - } catch (Exception $e) { - $this->logger->critical($e); - - throw new CommandException(__('There was an error while trying to process the request.')); - } - - $result = $this->validator->validate( - array_merge($commandSubject, ['response' => $response]) - ); - if (!$result->isValid()) { - throw new CommandException(__('There was an error while trying to process the request.')); - } - - return new ArrayResult($response); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/RefundTransactionStrategyCommand.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/RefundTransactionStrategyCommand.php deleted file mode 100644 index de3ded6515ae0..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Command/RefundTransactionStrategyCommand.php +++ /dev/null @@ -1,106 +0,0 @@ -commandPool = $commandPool; - $this->subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function execute(array $commandSubject): void - { - $command = $this->getCommand($commandSubject); - - $this->commandPool->get($command) - ->execute($commandSubject); - } - - /** - * Determines the command that should be used based on the status of the transaction - * - * @param array $commandSubject - * @return string - * @throws CommandException - * @throws \Magento\Framework\Exception\NotFoundException - */ - private function getCommand(array $commandSubject): string - { - $details = $this->commandPool->get('get_transaction_details') - ->execute($commandSubject) - ->get(); - - if ($this->canVoid($details, $commandSubject)) { - return self::VOID; - } - - if ($details['transaction']['transactionStatus'] !== 'settledSuccessfully') { - throw new CommandException(__('This transaction cannot be refunded with its current status.')); - } - - return self::REFUND; - } - - /** - * Checks if void command can be performed. - * - * @param array $details - * @param array $commandSubject - * @return bool - * @throws CommandException - */ - private function canVoid(array $details, array $commandSubject) :bool - { - if ($details['transaction']['transactionStatus'] === 'capturedPendingSettlement') { - if ((float) $details['transaction']['authAmount'] !== (float) $commandSubject['amount']) { - throw new CommandException( - __('The transaction has not been settled, a partial refund is not yet available.') - ); - } - - return true; - } - - return false; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Config.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Config.php deleted file mode 100644 index f41eb1660da55..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Config.php +++ /dev/null @@ -1,189 +0,0 @@ -getValue(Config::KEY_LOGIN_ID, $storeId); - } - - /** - * Gets the current environment - * - * @param int|null $storeId - * @return string - */ - public function getEnvironment($storeId = null): string - { - return $this->getValue(Config::KEY_ENVIRONMENT, $storeId); - } - - /** - * Gets the transaction key - * - * @param int|null $storeId - * @return string - */ - public function getTransactionKey($storeId = null): ?string - { - return $this->getValue(Config::KEY_TRANSACTION_KEY, $storeId); - } - - /** - * Gets the API endpoint URL - * - * @param int|null $storeId - * @return string - */ - public function getApiUrl($storeId = null): string - { - $environment = $this->getValue(Config::KEY_ENVIRONMENT, $storeId); - - return $environment === Environment::ENVIRONMENT_SANDBOX - ? self::ENDPOINT_URL_SANDBOX - : self::ENDPOINT_URL_PRODUCTION; - } - - /** - * Gets the configured signature key - * - * @param int|null $storeId - * @return string - */ - public function getTransactionSignatureKey($storeId = null): ?string - { - return $this->getValue(Config::KEY_SIGNATURE_KEY, $storeId); - } - - /** - * Gets the configured legacy transaction hash - * - * @param int|null $storeId - * @return string - */ - public function getLegacyTransactionHash($storeId = null): ?string - { - return $this->getValue(Config::KEY_LEGACY_TRANSACTION_HASH, $storeId); - } - - /** - * Gets the configured payment action - * - * @param int|null $storeId - * @return string - */ - public function getPaymentAction($storeId = null): ?string - { - return $this->getValue(Config::KEY_PAYMENT_ACTION, $storeId); - } - - /** - * Gets the configured client key - * - * @param int|null $storeId - * @return string - */ - public function getClientKey($storeId = null): ?string - { - return $this->getValue(Config::KEY_CLIENT_KEY, $storeId); - } - - /** - * Should authorize.net email the customer their receipt. - * - * @param int|null $storeId - * @return bool - */ - public function shouldEmailCustomer($storeId = null): bool - { - return (bool)$this->getValue(Config::KEY_SHOULD_EMAIL_CUSTOMER, $storeId); - } - - /** - * Should the cvv field be shown - * - * @param int|null $storeId - * @return bool - */ - public function isCvvEnabled($storeId = null): bool - { - return (bool)$this->getValue(Config::KEY_CVV_ENABLED, $storeId); - } - - /** - * Retrieves the solution id for the given store based on environment - * - * @param int|null $storeId - * @return string - */ - public function getSolutionId($storeId = null): ?string - { - $environment = $this->getValue(Config::KEY_ENVIRONMENT, $storeId); - - return $environment === Environment::ENVIRONMENT_SANDBOX - ? self::SOLUTION_ID_SANDBOX - : self::SOLUTION_ID_PRODUCTION; - } - - /** - * Returns the keys to be pulled from the transaction and displayed - * - * @param int|null $storeId - * @return string[] - */ - public function getAdditionalInfoKeys($storeId = null): array - { - return explode(',', $this->getValue(Config::KEY_ADDITIONAL_INFO_KEYS, $storeId) ?? ''); - } - - /** - * Returns the keys to be pulled from the transaction and displayed when syncing the transaction - * - * @param int|null $storeId - * @return string[] - */ - public function getTransactionInfoSyncKeys($storeId = null): array - { - return explode(',', $this->getValue(Config::KEY_TRANSACTION_SYNC_KEYS, $storeId) ?? ''); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Client.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Client.php deleted file mode 100644 index ebd4240108a09..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Client.php +++ /dev/null @@ -1,131 +0,0 @@ -httpClientFactory = $httpClientFactory; - $this->config = $config; - $this->paymentLogger = $paymentLogger; - $this->logger = $logger; - $this->json = $json; - } - - /** - * Places request to gateway. Returns result as ENV array - * - * @param TransferInterface $transferObject - * @return array - * @throws \Magento\Payment\Gateway\Http\ClientException - */ - public function placeRequest(TransferInterface $transferObject) - { - $request = $transferObject->getBody(); - $log = [ - 'request' => $request, - ]; - $client = $this->httpClientFactory->create(); - $url = $this->config->getApiUrl(); - - $type = $request['payload_type']; - unset($request['payload_type']); - $request = [$type => $request]; - - try { - $client->setUri($url); - $client->setConfig(['maxredirects' => 0, 'timeout' => 30]); - $client->setRawData($this->json->serialize($request), 'application/json'); - $client->setMethod(ZendClient::POST); - - $responseBody = $client->request() - ->getBody(); - - // Strip BOM because Authorize.net sends it in the response - if ($responseBody && substr($responseBody, 0, 3) === pack('CCC', 0xef, 0xbb, 0xbf)) { - $responseBody = substr($responseBody, 3); - } - - $log['response'] = $responseBody; - - try { - $data = $this->json->unserialize($responseBody); - } catch (InvalidArgumentException $e) { - // phpcs:ignore Magento2.Exceptions.DirectThrow - throw new \Exception('Invalid JSON was returned by the gateway'); - } - - return $data; - // phpcs:ignore Magento2.Exceptions.ThrowCatch - } catch (\Exception $e) { - $this->logger->critical($e); - - throw new ClientException( - __('Something went wrong in the payment gateway.') - ); - } finally { - $this->paymentLogger->debug($log); - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Payload/Filter/RemoveFieldsFilter.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Payload/Filter/RemoveFieldsFilter.php deleted file mode 100644 index cce878cfbbb16..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Payload/Filter/RemoveFieldsFilter.php +++ /dev/null @@ -1,45 +0,0 @@ -fields = $fields; - } - - /** - * @inheritdoc - */ - public function filter(array $data): array - { - foreach ($this->fields as $field) { - unset($data[$field]); - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Payload/FilterInterface.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Payload/FilterInterface.php deleted file mode 100644 index dade4bd4ee1f3..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Http/Payload/FilterInterface.php +++ /dev/null @@ -1,26 +0,0 @@ -transferBuilder = $transferBuilder; - $this->payloadFilters = $payloadFilters; - } - - /** - * Builds gateway transfer object - * - * @param array $request - * @return TransferInterface - */ - public function create(array $request) - { - foreach ($this->payloadFilters as $filter) { - $request = $filter->filter($request); - } - - return $this->transferBuilder - ->setBody($request) - ->build(); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AcceptFdsDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AcceptFdsDataBuilder.php deleted file mode 100644 index 4a673112e6a5f..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AcceptFdsDataBuilder.php +++ /dev/null @@ -1,68 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $authorizationTransaction = $payment->getAuthorizationTransaction(); - - if (empty($authorizationTransaction)) { - $transactionId = $payment->getLastTransId(); - } else { - $transactionId = $authorizationTransaction->getParentTxnId(); - - if (empty($transactionId)) { - $transactionId = $authorizationTransaction->getTxnId(); - } - } - - $data = [ - 'heldTransactionRequest' => [ - 'action' => 'approve', - 'refTransId' => $transactionId, - ] - ]; - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AddressDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AddressDataBuilder.php deleted file mode 100644 index 07a4921b7d60b..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AddressDataBuilder.php +++ /dev/null @@ -1,80 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $order = $paymentDO->getOrder(); - $billingAddress = $order->getBillingAddress(); - $shippingAddress = $order->getShippingAddress(); - $result = [ - 'transactionRequest' => [] - ]; - - if ($billingAddress) { - $result['transactionRequest']['billTo'] = [ - 'firstName' => $billingAddress->getFirstname(), - 'lastName' => $billingAddress->getLastname(), - 'company' => $billingAddress->getCompany() ?? '', - 'address' => $billingAddress->getStreetLine1(), - 'city' => $billingAddress->getCity(), - 'state' => $billingAddress->getRegionCode(), - 'zip' => $billingAddress->getPostcode(), - 'country' => $billingAddress->getCountryId() - ]; - } - - if ($shippingAddress) { - $result['transactionRequest']['shipTo'] = [ - 'firstName' => $shippingAddress->getFirstname(), - 'lastName' => $shippingAddress->getLastname(), - 'company' => $shippingAddress->getCompany() ?? '', - 'address' => $shippingAddress->getStreetLine1(), - 'city' => $shippingAddress->getCity(), - 'state' => $shippingAddress->getRegionCode(), - 'zip' => $shippingAddress->getPostcode(), - 'country' => $shippingAddress->getCountryId() - ]; - } - - if ($order->getRemoteIp()) { - $result['transactionRequest']['customerIP'] = $order->getRemoteIp(); - } - - return $result; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AmountDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AmountDataBuilder.php deleted file mode 100644 index 07fae5e536a28..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AmountDataBuilder.php +++ /dev/null @@ -1,49 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - return [ - 'transactionRequest' => [ - 'amount' => $this->formatPrice($this->subjectReader->readAmount($buildSubject)), - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AuthenticationDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AuthenticationDataBuilder.php deleted file mode 100644 index dec6626dc7524..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AuthenticationDataBuilder.php +++ /dev/null @@ -1,62 +0,0 @@ -subjectReader = $subjectReader; - $this->config = $config; - } - - /** - * Adds authentication information to the request - * - * @param array $buildSubject - * @return array - */ - public function build(array $buildSubject): array - { - $storeId = $this->subjectReader->readStoreId($buildSubject); - - return [ - 'merchantAuthentication' => [ - 'name' => $this->config->getLoginId($storeId), - 'transactionKey' => $this->config->getTransactionKey($storeId) - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AuthorizeDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AuthorizeDataBuilder.php deleted file mode 100644 index c440da3ca9f4f..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/AuthorizeDataBuilder.php +++ /dev/null @@ -1,72 +0,0 @@ -subjectReader = $subjectReader; - $this->passthroughData = $passthroughData; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $data = [ - 'transactionRequest' => [ - 'transactionType' => self::REQUEST_AUTH_ONLY, - ] - ]; - - $this->passthroughData->setData( - 'transactionType', - $data['transactionRequest']['transactionType'] - ); - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CaptureDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CaptureDataBuilder.php deleted file mode 100644 index 1e2a8617907a0..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CaptureDataBuilder.php +++ /dev/null @@ -1,76 +0,0 @@ -subjectReader = $subjectReader; - $this->passthroughData = $passthroughData; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $authTransaction = $payment->getAuthorizationTransaction(); - $refId = $authTransaction->getAdditionalInformation('real_transaction_id'); - - $data = [ - 'transactionRequest' => [ - 'transactionType' => self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE, - 'refTransId' => $refId - ] - ]; - - $this->passthroughData->setData( - 'transactionType', - $data['transactionRequest']['transactionType'] - ); - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CustomSettingsBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CustomSettingsBuilder.php deleted file mode 100644 index 31246497fca92..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CustomSettingsBuilder.php +++ /dev/null @@ -1,65 +0,0 @@ -subjectReader = $subjectReader; - $this->config = $config; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $result = []; - - if ($this->config->shouldEmailCustomer($this->subjectReader->readStoreId($buildSubject))) { - $result['transactionRequest'] = [ - 'transactionSettings' => [ - 'setting' => [ - [ - 'settingName' => 'emailCustomer', - 'settingValue' => 'true' - ] - ] - ] - ]; - } - - return $result; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CustomerDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CustomerDataBuilder.php deleted file mode 100644 index cfdaa31552960..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/CustomerDataBuilder.php +++ /dev/null @@ -1,55 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $order = $paymentDO->getOrder(); - $billingAddress = $order->getBillingAddress(); - $result = [ - 'transactionRequest' => [ - 'customer' => [ - 'id' => $order->getCustomerId(), - 'email' => $billingAddress->getEmail() - ] - ] - ]; - - return $result; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/OrderDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/OrderDataBuilder.php deleted file mode 100644 index bf0a15f552e6c..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/OrderDataBuilder.php +++ /dev/null @@ -1,51 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $order = $paymentDO->getOrder(); - - return [ - 'transactionRequest' => [ - 'order' => [ - 'invoiceNumber' => $order->getOrderIncrementId() - ] - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PassthroughDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PassthroughDataBuilder.php deleted file mode 100644 index 6e6ef04972c78..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PassthroughDataBuilder.php +++ /dev/null @@ -1,61 +0,0 @@ -passthroughData = $passthroughData; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $fields = []; - - foreach ($this->passthroughData->getData() as $key => $value) { - $fields[] = [ - 'name' => $key, - 'value' => $value - ]; - } - - if (!empty($fields)) { - return [ - 'transactionRequest' => [ - 'userFields' => [ - 'userField' => $fields - ] - ] - ]; - } - - return []; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PaymentDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PaymentDataBuilder.php deleted file mode 100644 index 99955e9724577..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PaymentDataBuilder.php +++ /dev/null @@ -1,59 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $dataDescriptor = $payment->getAdditionalInformation('opaqueDataDescriptor'); - $dataValue = $payment->getAdditionalInformation('opaqueDataValue'); - - $data['transactionRequest']['payment'] = [ - 'opaqueData' => [ - 'dataDescriptor' => $dataDescriptor, - 'dataValue' => $dataValue - ] - ]; - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PoDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PoDataBuilder.php deleted file mode 100644 index 9b56e0852af01..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/PoDataBuilder.php +++ /dev/null @@ -1,55 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $data = [ - 'transactionRequest' => [ - 'poNumber' => $payment->getPoNumber() - ] - ]; - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundPaymentDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundPaymentDataBuilder.php deleted file mode 100644 index ac5bcb08cb04a..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundPaymentDataBuilder.php +++ /dev/null @@ -1,61 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - * @throws \Exception - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $data = [ - 'transactionRequest' => [ - 'payment' => [ - 'creditCard' => [ - 'cardNumber' => $payment->getAdditionalInformation('ccLast4'), - 'expirationDate' => 'XXXX' - ] - ] - ] - ]; - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundReferenceTransactionDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundReferenceTransactionDataBuilder.php deleted file mode 100644 index 65842354b7e2a..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundReferenceTransactionDataBuilder.php +++ /dev/null @@ -1,56 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $transactionId = $payment->getAuthorizationTransaction()->getParentTxnId(); - $data = [ - 'transactionRequest' => [ - 'refTransId' => $transactionId - ] - ]; - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundTransactionTypeDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundTransactionTypeDataBuilder.php deleted file mode 100644 index 0f74299ebf5bd..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RefundTransactionTypeDataBuilder.php +++ /dev/null @@ -1,34 +0,0 @@ - [ - 'transactionType' => self::REQUEST_TYPE_REFUND - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RequestTypeBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RequestTypeBuilder.php deleted file mode 100644 index d20add70846b8..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/RequestTypeBuilder.php +++ /dev/null @@ -1,48 +0,0 @@ -type = $type; - } - - /** - * Adds the type of the request to the build subject - * - * @param array $buildSubject - * @return array - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function build(array $buildSubject): array - { - return [ - 'payload_type' => $this->type - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/SaleDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/SaleDataBuilder.php deleted file mode 100644 index 4402fb5af8c82..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/SaleDataBuilder.php +++ /dev/null @@ -1,72 +0,0 @@ -subjectReader = $subjectReader; - $this->passthroughData = $passthroughData; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $data = [ - 'transactionRequest' => [ - 'transactionType' => self::REQUEST_AUTH_AND_CAPTURE, - ] - ]; - - $this->passthroughData->setData( - 'transactionType', - $data['transactionRequest']['transactionType'] - ); - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/ShippingDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/ShippingDataBuilder.php deleted file mode 100644 index ea2cb89971fb5..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/ShippingDataBuilder.php +++ /dev/null @@ -1,59 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $order = $paymentDO->getOrder(); - $data = []; - - if ($payment instanceof Payment && $order instanceof Order) { - $data = [ - 'transactionRequest' => [ - 'shipping' => [ - 'amount' => $order->getBaseShippingAmount() - ] - ] - ]; - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/SolutionDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/SolutionDataBuilder.php deleted file mode 100644 index 8734c0ab454ce..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/SolutionDataBuilder.php +++ /dev/null @@ -1,56 +0,0 @@ -config = $config; - $this->subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - return [ - 'transactionRequest' => [ - 'solution' => [ - 'id' => $this->config->getSolutionId($this->subjectReader->readStoreId($buildSubject)), - ] - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/StoreConfigBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/StoreConfigBuilder.php deleted file mode 100644 index 396ad143466cd..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/StoreConfigBuilder.php +++ /dev/null @@ -1,46 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $order = $paymentDO->getOrder(); - - return [ - 'store_id' => $order->getStoreId() - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/StubDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/StubDataBuilder.php deleted file mode 100644 index a2766d97d9299..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/StubDataBuilder.php +++ /dev/null @@ -1,31 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $data = []; - - if (!empty($buildSubject['transactionId'])) { - $data = [ - 'transId' => $buildSubject['transactionId'] - ]; - } else { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - - if ($payment instanceof Payment) { - $authorizationTransaction = $payment->getAuthorizationTransaction(); - - if (empty($authorizationTransaction)) { - $transactionId = $payment->getLastTransId(); - } else { - $transactionId = $authorizationTransaction->getParentTxnId(); - - if (empty($transactionId)) { - $transactionId = $authorizationTransaction->getTxnId(); - } - } - - $data = [ - 'transId' => $transactionId - ]; - } - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/VoidDataBuilder.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/VoidDataBuilder.php deleted file mode 100644 index c830f1f23d17c..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Request/VoidDataBuilder.php +++ /dev/null @@ -1,63 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $transactionData = []; - - if ($payment instanceof Payment) { - $authorizationTransaction = $payment->getAuthorizationTransaction(); - $refId = $authorizationTransaction->getAdditionalInformation('real_transaction_id'); - if (empty($refId)) { - $refId = $authorizationTransaction->getParentTxnId(); - } - - $transactionData['transactionRequest'] = [ - 'transactionType' => self::REQUEST_TYPE_VOID, - 'refTransId' => $refId - ]; - } - - return $transactionData; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseParentTransactionHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseParentTransactionHandler.php deleted file mode 100644 index 60c5bb21c0865..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseParentTransactionHandler.php +++ /dev/null @@ -1,48 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response): void - { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - - if ($payment instanceof Payment) { - $payment->setShouldCloseParentTransaction(true); - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/ClosePartialTransactionHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/ClosePartialTransactionHandler.php deleted file mode 100644 index 5279df56b5e28..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/ClosePartialTransactionHandler.php +++ /dev/null @@ -1,30 +0,0 @@ -getCreditmemo()->getInvoice()->canRefund(); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseTransactionHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseTransactionHandler.php deleted file mode 100644 index 2cccf255ab8e9..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseTransactionHandler.php +++ /dev/null @@ -1,68 +0,0 @@ -subjectReader = $subjectReader; - $this->closeTransaction = $closeTransaction; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response): void - { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - - if ($payment instanceof Payment) { - $payment->setIsTransactionClosed($this->closeTransaction); - $payment->setShouldCloseParentTransaction($this->shouldCloseParentTransaction($payment)); - } - } - - /** - * Whether parent transaction should be closed. - * - * @param Payment $payment - * @return bool - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function shouldCloseParentTransaction(Payment $payment) - { - return true; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/PaymentResponseHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/PaymentResponseHandler.php deleted file mode 100644 index e0b192205012f..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/PaymentResponseHandler.php +++ /dev/null @@ -1,58 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response): void - { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - $transactionResponse = $response['transactionResponse']; - - if ($payment instanceof Payment) { - $payment->setCcLast4($payment->getAdditionalInformation('ccLast4')); - $payment->setCcAvsStatus($transactionResponse['avsResultCode']); - $payment->setIsTransactionClosed(false); - - if ($transactionResponse['responseCode'] == self::RESPONSE_CODE_HELD) { - $payment->setIsTransactionPending(true) - ->setIsFraudDetected(true); - } - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/PaymentReviewStatusHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/PaymentReviewStatusHandler.php deleted file mode 100644 index 41c2ddd2b3271..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/PaymentReviewStatusHandler.php +++ /dev/null @@ -1,66 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response): void - { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - - if ($payment instanceof Payment) { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - - $status = $response['transaction']['transactionStatus']; - // This data is only used when updating the order payment via Get Payment Update - if (!in_array($status, self::REVIEW_PENDING_STATUSES)) { - $denied = in_array($status, self::REVIEW_DECLINED_STATUSES); - $payment->setData('is_transaction_denied', $denied); - $payment->setData('is_transaction_approved', !$denied); - } - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/TransactionDetailsResponseHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/TransactionDetailsResponseHandler.php deleted file mode 100644 index 81bb9c92b15ed..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/TransactionDetailsResponseHandler.php +++ /dev/null @@ -1,68 +0,0 @@ -subjectReader = $subjectReader; - $this->config = $config; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response): void - { - $storeId = $this->subjectReader->readStoreId($handlingSubject); - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - $transactionResponse = $response['transactionResponse']; - - if ($payment instanceof Payment) { - // Add the keys that should show in the transaction details interface - $additionalInformationKeys = $this->config->getAdditionalInfoKeys($storeId); - $rawDetails = []; - foreach ($additionalInformationKeys as $paymentInfoKey) { - if (isset($transactionResponse[$paymentInfoKey])) { - $rawDetails[$paymentInfoKey] = $transactionResponse[$paymentInfoKey]; - $payment->setAdditionalInformation($paymentInfoKey, $transactionResponse[$paymentInfoKey]); - } - } - $payment->setTransactionAdditionalInfo(Payment\Transaction::RAW_DETAILS, $rawDetails); - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/TransactionIdHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/TransactionIdHandler.php deleted file mode 100644 index f3a9a0a1c4466..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/TransactionIdHandler.php +++ /dev/null @@ -1,57 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response): void - { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - $transactionResponse = $response['transactionResponse']; - - if ($payment instanceof Payment) { - if (!$payment->getParentTransactionId() - || $transactionResponse['transId'] != $payment->getParentTransactionId() - ) { - $payment->setTransactionId($transactionResponse['transId']); - } - $payment->setTransactionAdditionalInfo( - 'real_transaction_id', - $transactionResponse['transId'] - ); - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/VoidResponseHandler.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/VoidResponseHandler.php deleted file mode 100644 index 7bcb8c6c8dba1..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Response/VoidResponseHandler.php +++ /dev/null @@ -1,52 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response): void - { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $payment = $paymentDO->getPayment(); - $transactionId = $response['transactionResponse']['transId']; - - if ($payment instanceof Payment) { - $payment->setIsTransactionClosed(true); - $payment->setShouldCloseParentTransaction(true); - $payment->setTransactionAdditionalInfo('real_transaction_id', $transactionId); - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/SubjectReader.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/SubjectReader.php deleted file mode 100644 index b5f1cef94ea46..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/SubjectReader.php +++ /dev/null @@ -1,100 +0,0 @@ -readPayment($subject) - ->getOrder() - ->getStoreId(); - // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock - } catch (\InvalidArgumentException $e) { - // No store id is current set - } - } - - return $storeId ? (int)$storeId : null; - } - - /** - * Reads amount from subject - * - * @param array $subject - * @return string - */ - public function readAmount(array $subject): string - { - return (string)Helper\SubjectReader::readAmount($subject); - } - - /** - * Reads response from subject - * - * @param array $subject - * @return array - */ - public function readResponse(array $subject): ?array - { - return Helper\SubjectReader::readResponse($subject); - } - - /** - * Reads login id from subject - * - * @param array $subject - * @return string|null - */ - public function readLoginId(array $subject): ?string - { - return $subject['merchantAuthentication']['name'] ?? null; - } - - /** - * Reads transaction key from subject - * - * @param array $subject - * @return string|null - */ - public function readTransactionKey(array $subject): ?string - { - return $subject['merchantAuthentication']['transactionKey'] ?? null; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/GeneralResponseValidator.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/GeneralResponseValidator.php deleted file mode 100644 index 47065ed96c240..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/GeneralResponseValidator.php +++ /dev/null @@ -1,82 +0,0 @@ -resultFactory = $resultFactory; - $this->subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function validate(array $validationSubject): ResultInterface - { - $response = $this->subjectReader->readResponse($validationSubject); - $isValid = (isset($response['messages']['resultCode']) - && $response['messages']['resultCode'] === self::RESULT_CODE_SUCCESS); - $errorCodes = []; - $errorMessages = []; - - if (!$isValid) { - if (isset($response['messages']['message']['code'])) { - $errorCodes[] = $response['messages']['message']['code']; - $errorMessages[] = $response['messages']['message']['text']; - } elseif (isset($response['messages']['message'])) { - foreach ($response['messages']['message'] as $message) { - $errorCodes[] = $message['code']; - $errorMessages[] = $message['text']; - } - } elseif (isset($response['errors']['error'])) { - foreach ($response['errors']['error'] as $message) { - $errorCodes[] = $message['errorCode']; - $errorMessages[] = $message['errorText']; - } - } - } - - return $this->createResult($isValid, $errorMessages, $errorCodes); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionHashValidator.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionHashValidator.php deleted file mode 100644 index c11e22110d952..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionHashValidator.php +++ /dev/null @@ -1,201 +0,0 @@ -subjectReader = $subjectReader; - $this->config = $config; - } - - /** - * Validates the transaction hash matches the configured hash - * - * @param array $validationSubject - * @return ResultInterface - */ - public function validate(array $validationSubject): ResultInterface - { - $response = $this->subjectReader->readResponse($validationSubject); - $storeId = $this->subjectReader->readStoreId($validationSubject); - - if (!empty($response['transactionResponse']['transHashSha2'])) { - return $this->validateHash( - $validationSubject, - $this->config->getTransactionSignatureKey($storeId), - 'transHashSha2', - 'generateSha512Hash' - ); - } elseif (!empty($response['transactionResponse']['transHash'])) { - return $this->validateHash( - $validationSubject, - $this->config->getLegacyTransactionHash($storeId), - 'transHash', - 'generateMd5Hash' - ); - } - - return $this->createResult( - false, - [ - __('The authenticity of the gateway response could not be verified.') - ], - [self::ERROR_TRANSACTION_HASH] - ); - } - - /** - * Validates the response again the legacy MD5 spec - * - * @param array $validationSubject - * @param string $storedHash - * @param string $hashField - * @param string $generateFunction - * @return ResultInterface - */ - private function validateHash( - array $validationSubject, - string $storedHash, - string $hashField, - string $generateFunction - ): ResultInterface { - $storeId = $this->subjectReader->readStoreId($validationSubject); - $response = $this->subjectReader->readResponse($validationSubject); - $transactionResponse = $response['transactionResponse']; - - /* - * Authorize.net is inconsistent with how they hash and heuristically trying to detect whether or not they used - * the amount to calculate the hash is risky because their responses are incorrect in some cases. - * Refund uses the amount when referencing a transaction but will use 0 when refunding without a reference. - * Non-refund reference transactions such as (void/capture) don't use the amount. Authorize/auth&capture - * transactions will use amount but if there is an AVS error the response will indicate the transaction was a - * reference transaction so this can't be heuristically detected by looking at combinations of refTransID - * and transId (yes they also mixed the letter casing for "id"). Their documentation doesn't talk about this - * and to make this even better, none of their official SDKs support the new hash field to compare - * implementations. Therefore the only way to safely validate this hash without failing for even more - * unexpected corner cases we simply need to validate with and without the amount. - */ - try { - $amount = $this->subjectReader->readAmount($validationSubject); - } catch (\InvalidArgumentException $e) { - $amount = 0; - } - - $hash = $this->{$generateFunction}( - $storedHash, - $this->config->getLoginId($storeId), - sprintf('%.2F', $amount), - $transactionResponse['transId'] ?? '' - ); - $valid = Security::compareStrings($hash, $transactionResponse[$hashField]); - - if (!$valid && $amount > 0) { - $hash = $this->{$generateFunction}( - $storedHash, - $this->config->getLoginId($storeId), - '0.00', - $transactionResponse['transId'] ?? '' - ); - $valid = Security::compareStrings($hash, $transactionResponse[$hashField]); - } - - if ($valid) { - return $this->createResult(true); - } - - return $this->createResult( - false, - [ - __('The authenticity of the gateway response could not be verified.') - ], - [self::ERROR_TRANSACTION_HASH] - ); - } - - /** - * Generates a Md5 hash to compare against AuthNet's. - * - * @param string $merchantMd5 - * @param string $merchantApiLogin - * @param string $amount - * @param string $transactionId - * @return string - * @SuppressWarnings(PHPMD.UnusedPrivateMethod) - */ - private function generateMd5Hash( - $merchantMd5, - $merchantApiLogin, - $amount, - $transactionId - ) { - // phpcs:disable Magento2.Security.InsecureFunction - return strtoupper(md5($merchantMd5 . $merchantApiLogin . $transactionId . $amount)); - } - - /** - * Generates a SHA-512 hash to compare against AuthNet's. - * - * @param string $merchantKey - * @param string $merchantApiLogin - * @param string $amount - * @param string $transactionId - * @return string - * @SuppressWarnings(PHPMD.UnusedPrivateMethod) - */ - private function generateSha512Hash( - $merchantKey, - $merchantApiLogin, - $amount, - $transactionId - ) { - $message = '^' . $merchantApiLogin . '^' . $transactionId . '^' . $amount . '^'; - - return strtoupper(hash_hmac('sha512', $message, pack('H*', $merchantKey))); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php b/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php deleted file mode 100644 index 8238aa37dcc0a..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Gateway/Validator/TransactionResponseValidator.php +++ /dev/null @@ -1,102 +0,0 @@ -subjectReader = $subjectReader; - } - - /** - * @inheritdoc - */ - public function validate(array $validationSubject): ResultInterface - { - $response = $this->subjectReader->readResponse($validationSubject); - $transactionResponse = $response['transactionResponse']; - - if ($this->isResponseCodeAnError($transactionResponse)) { - $errorCodes = []; - $errorMessages = []; - - if (isset($transactionResponse['messages']['message']['code'])) { - $errorCodes[] = $transactionResponse['messages']['message']['code']; - $errorMessages[] = $transactionResponse['messages']['message']['text']; - } elseif (isset($transactionResponse['messages']['message'])) { - foreach ($transactionResponse['messages']['message'] as $message) { - $errorCodes[] = $message['code']; - $errorMessages[] = $message['description']; - } - } elseif (isset($transactionResponse['errors'])) { - foreach ($transactionResponse['errors'] as $message) { - $errorCodes[] = $message['errorCode']; - $errorMessages[] = $message['errorText']; - } - } - - return $this->createResult(false, $errorMessages, $errorCodes); - } - - return $this->createResult(true); - } - - /** - * Determines if the response code is actually an error - * - * @param array $transactionResponse - * @return bool - */ - private function isResponseCodeAnError(array $transactionResponse): bool - { - $code = $transactionResponse['messages']['message']['code'] - ?? $transactionResponse['messages']['message'][0]['code'] - ?? $transactionResponse['errors'][0]['errorCode'] - ?? null; - - return !in_array($transactionResponse['responseCode'], [self::RESPONSE_CODE_APPROVED, self::RESPONSE_CODE_HELD]) - || $code - && !in_array( - $code, - [ - self::RESPONSE_REASON_CODE_APPROVED, - self::RESPONSE_REASON_CODE_PENDING_REVIEW, - self::RESPONSE_REASON_CODE_PENDING_REVIEW_AUTHORIZED - ] - ); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Model/Adminhtml/Source/Cctype.php b/app/code/Magento/AuthorizenetAcceptjs/Model/Adminhtml/Source/Cctype.php deleted file mode 100644 index cdd1745a6bc1e..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Model/Adminhtml/Source/Cctype.php +++ /dev/null @@ -1,28 +0,0 @@ - self::ENVIRONMENT_SANDBOX, - 'label' => 'Sandbox', - ], - [ - 'value' => self::ENVIRONMENT_PRODUCTION, - 'label' => 'Production' - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Model/Adminhtml/Source/PaymentAction.php b/app/code/Magento/AuthorizenetAcceptjs/Model/Adminhtml/Source/PaymentAction.php deleted file mode 100644 index 953841604bfee..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Model/Adminhtml/Source/PaymentAction.php +++ /dev/null @@ -1,35 +0,0 @@ - 'authorize', - 'label' => __('Authorize Only'), - ], - [ - 'value' => 'authorize_capture', - 'label' => __('Authorize and Capture') - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Model/PassthroughDataObject.php b/app/code/Magento/AuthorizenetAcceptjs/Model/PassthroughDataObject.php deleted file mode 100644 index 145d8c000e8f7..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Model/PassthroughDataObject.php +++ /dev/null @@ -1,22 +0,0 @@ -config = $config; - $this->cart = $cart; - } - - /** - * Retrieve assoc array of checkout configuration - * - * @return array - */ - public function getConfig() - { - $storeId = $this->cart->getStoreId(); - - return [ - 'payment' => [ - Config::METHOD => [ - 'clientKey' => $this->config->getClientKey($storeId), - 'apiLoginID' => $this->config->getLoginId($storeId), - 'environment' => $this->config->getEnvironment($storeId), - 'useCvv' => $this->config->isCvvEnabled($storeId), - ] - ] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Observer/DataAssignObserver.php b/app/code/Magento/AuthorizenetAcceptjs/Observer/DataAssignObserver.php deleted file mode 100644 index 0f989bb032175..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Observer/DataAssignObserver.php +++ /dev/null @@ -1,55 +0,0 @@ -readDataArgument($observer); - - $additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA); - if (!is_array($additionalData)) { - return; - } - - $paymentInfo = $this->readPaymentModelArgument($observer); - - foreach ($this->additionalInformationList as $additionalInformationKey) { - if (isset($additionalData[$additionalInformationKey])) { - $paymentInfo->setAdditionalInformation( - $additionalInformationKey, - $additionalData[$additionalInformationKey] - ); - } - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/README.md b/app/code/Magento/AuthorizenetAcceptjs/README.md deleted file mode 100644 index b507f97a5a223..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Magento_AuthorizenetAcceptjs module - -The Magento_AuthorizenetAcceptjs module implements the integration with the Authorize.Net payment gateway and makes the latter available as a payment method in Magento. - -## Installation details - -Before disabling or uninstalling this module, note that the `Magento_AuthorizenetCardinal` module depends on this module. - -For information about module installation in Magento 2, see [Enable or disable modules](https://devdocs.magento.com/guides/v2.3/install-gde/install/cli/install-cli-subcommands-enable.html). - -## Structure - -`Gateway/` - the directory that contains payment gateway command interfaces and service classes. - -For information about typical file structure of a module in Magento 2, see [Module file structure](http://devdocs.magento.com/guides/v2.3/extension-dev-guide/build/module-file-structure.html#module-file-structure). - -## Extensibility - -Extension developers can interact with the Magento_AuthorizenetAcceptjs module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). - -[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_AuthorizenetAcceptjs module. - -### Events - -This module observes the following events: - -- `payment_method_assign_data_authorizenet_acceptjs` event in the `Magento\AuthorizenetAcceptjs\Observer\DataAssignObserver` file. - -For information about an event in Magento 2, see [Events and observers](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/events-and-observers.html#events). diff --git a/app/code/Magento/AuthorizenetAcceptjs/Setup/Patch/Data/CopyCurrentConfig.php b/app/code/Magento/AuthorizenetAcceptjs/Setup/Patch/Data/CopyCurrentConfig.php deleted file mode 100644 index aa699569c61f6..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Setup/Patch/Data/CopyCurrentConfig.php +++ /dev/null @@ -1,233 +0,0 @@ -scopeConfig = $scopeConfig; - $this->resourceConfig = $resourceConfig; - $this->encryptor = $encryptor; - $this->moduleDataSetup = $moduleDataSetup; - $this->storeManager = $storeManager; - } - - /** - * @inheritdoc - */ - public function apply(): void - { - $this->moduleDataSetup->startSetup(); - $this->migrateDefaultValues(); - $this->migrateWebsiteValues(); - $this->moduleDataSetup->endSetup(); - } - - /** - * Migrate configuration values from DirectPost to Accept.js on default scope - * - * @return void - */ - private function migrateDefaultValues(): void - { - foreach ($this->configFieldsToMigrate as $field) { - $configValue = $this->getOldConfigValue($field); - - if (!empty($configValue)) { - $this->saveNewConfigValue($field, $configValue); - } - } - - foreach ($this->encryptedConfigFieldsToMigrate as $field) { - $configValue = $this->getOldConfigValue($field); - - if (!empty($configValue)) { - $this->saveNewConfigValue( - $field, - $configValue, - ScopeConfigInterface::SCOPE_TYPE_DEFAULT, - 0, - true - ); - } - } - } - - /** - * Migrate configuration values from DirectPost to Accept.js on all website scopes - * - * @return void - */ - private function migrateWebsiteValues(): void - { - foreach ($this->storeManager->getWebsites() as $website) { - $websiteID = (int) $website->getId(); - - foreach ($this->configFieldsToMigrate as $field) { - $configValue = $this->getOldConfigValue($field, ScopeInterface::SCOPE_WEBSITES, $websiteID); - - if (!empty($configValue)) { - $this->saveNewConfigValue($field, $configValue, ScopeInterface::SCOPE_WEBSITES, $websiteID); - } - } - - foreach ($this->encryptedConfigFieldsToMigrate as $field) { - $configValue = $this->getOldConfigValue($field, ScopeInterface::SCOPE_WEBSITES, $websiteID); - - if (!empty($configValue)) { - $this->saveNewConfigValue($field, $configValue, ScopeInterface::SCOPE_WEBSITES, $websiteID, true); - } - } - } - } - - /** - * Get old configuration value from the DirectPost module's configuration on the store scope - * - * @param string $field - * @param string $scope - * @param int $scopeID - * @return mixed - */ - private function getOldConfigValue( - string $field, - string $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, - int $scopeID = null - ) { - return $this->scopeConfig->getValue( - sprintf(self::PAYMENT_PATH_FORMAT, self::DIRECTPOST_PATH, $field), - $scope, - $scopeID - ); - } - - /** - * Save configuration value for AcceptJS - * - * @param string $field - * @param mixed $value - * @param string $scope - * @param int $scopeID - * @param bool $isEncrypted - * @return void - */ - private function saveNewConfigValue( - string $field, - $value, - string $scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, - int $scopeID = 0, - bool $isEncrypted = false - ): void { - $value = $isEncrypted ? $this->encryptor->encrypt($value) : $value; - - $this->resourceConfig->saveConfig( - sprintf(self::PAYMENT_PATH_FORMAT, self::ACCEPTJS_PATH, $field), - $value, - $scope, - $scopeID - ); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/README.md b/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/README.md deleted file mode 100644 index aba235e2cfad9..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# AuthorizenetAcceptjs Functional Tests - -The Functional Test Module for **Magento AuthorizenetAcceptjs** module. diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/FormTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/FormTest.php deleted file mode 100644 index 020b651aaaf17..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/FormTest.php +++ /dev/null @@ -1,59 +0,0 @@ -createMock(Context::class); - $this->configMock = $this->createMock(Config::class); - $quoteMock = $this->getMockBuilder(Quote::class) - ->disableOriginalConstructor() - ->setMethods(['getStoreId']) - ->getMock(); - $quoteMock->method('getStoreId') - ->willReturn('123'); - $paymentConfig = $this->createMock(PaymentConfig::class); - - $this->block = new Form( - $contextMock, - $paymentConfig, - $this->configMock, - $quoteMock - ); - } - - public function testIsCvvEnabled() - { - $this->configMock->method('isCvvEnabled') - ->with('123') - ->willReturn(true); - $this->assertTrue($this->block->isCvvEnabled()); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/InfoTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/InfoTest.php deleted file mode 100644 index 70dfb140e1576..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/InfoTest.php +++ /dev/null @@ -1,80 +0,0 @@ -createMock(Context::class); - /** @var Config|MockObject|InvocationMocker $configMock */ - $configMock = $this->createMock(ConfigInterface::class); - $block = new Info($contextMock, $configMock); - /** @var InfoInterface|MockObject|InvocationMocker $payment */ - $payment = $this->createMock(InfoInterface::class); - /** @var RendererInterface|MockObject|InvocationMocker $translationRenderer */ - $translationRenderer = $this->createMock(RendererInterface::class); - - // only foo should be used - $configMock->method('getValue') - ->willReturnMap([ - ['paymentInfoKeys', null, 'foo'], - ['privateInfoKeys', null, ''] - ]); - - // Give more info to ensure only foo is translated - $payment->method('getAdditionalInformation') - ->willReturnCallback(function ($name = null) { - $info = [ - 'foo' => 'bar', - 'baz' => 'bash' - ]; - - if (empty($name)) { - return $info; - } - - return $info[$name]; - }); - - // Foo should be translated to Super Cool String - $translationRenderer->method('render') - ->with(['foo'], []) - ->willReturn('Super Cool String'); - - $previousRenderer = Phrase::getRenderer(); - Phrase::setRenderer($translationRenderer); - - try { - $block->setData('info', $payment); - - $info = $block->getSpecificInformation(); - } finally { - // No matter what, restore the renderer - Phrase::setRenderer($previousRenderer); - } - - // Assert the label was correctly translated - $this->assertSame($info['Super Cool String'], 'bar'); - $this->assertArrayNotHasKey('foo', $info); - $this->assertArrayNotHasKey('baz', $info); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/PaymentTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/PaymentTest.php deleted file mode 100644 index 11ae27f9d2ea7..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Block/PaymentTest.php +++ /dev/null @@ -1,53 +0,0 @@ -createMock(Context::class); - $this->configMock = $this->createMock(ConfigProvider::class); - $this->block = new Payment($contextMock, $this->configMock, new Json()); - } - - public function testConfigIsCreated() - { - $this->configMock->method('getConfig') - ->willReturn([ - 'payment' => [ - 'authorizenet_acceptjs' => [ - 'foo' => 'bar' - ] - ] - ]); - - $result = $this->block->getPaymentConfig(); - $expected = '{"foo":"bar","code":"authorizenet_acceptjs"}'; - $this->assertEquals($expected, $result); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/AcceptPaymentStrategyCommandTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/AcceptPaymentStrategyCommandTest.php deleted file mode 100644 index 316fef5443360..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/AcceptPaymentStrategyCommandTest.php +++ /dev/null @@ -1,131 +0,0 @@ -transactionDetailsCommandMock = $this->createMock(CommandInterface::class); - $this->commandMock = $this->createMock(CommandInterface::class); - $this->transactionResultMock = $this->createMock(ResultInterface::class); - $this->commandPoolMock = $this->createMock(CommandPoolInterface::class); - $this->command = new AcceptPaymentStrategyCommand( - $this->commandPoolMock, - new SubjectReader() - ); - } - - /** - * @param string $status - * @dataProvider inReviewStatusesProvider - */ - public function testCommandWillAcceptInTheGatewayWhenInFDSReview(string $status) - { - // Assert command is executed - $this->commandMock->expects($this->once()) - ->method('execute'); - - $this->commandPoolMock->method('get') - ->willReturnMap([ - ['get_transaction_details', $this->transactionDetailsCommandMock], - ['accept_fds', $this->commandMock] - ]); - - $this->transactionResultMock->method('get') - ->willReturn([ - 'transaction' => [ - 'transactionStatus' => $status - ] - ]); - - $buildSubject = [ - 'foo' => '123' - ]; - - $this->transactionDetailsCommandMock->expects($this->once()) - ->method('execute') - ->with($buildSubject) - ->willReturn($this->transactionResultMock); - - $this->command->execute($buildSubject); - } - - public function testCommandWillDoNothingWhenTransactionHasAlreadyBeenAuthorized() - { - // Assert command is never executed - $this->commandMock->expects($this->never()) - ->method('execute'); - - $this->commandPoolMock->method('get') - ->willReturnMap([ - ['get_transaction_details', $this->transactionDetailsCommandMock], - ]); - - $this->transactionResultMock->method('get') - ->willReturn([ - 'transaction' => [ - 'transactionStatus' => 'anythingelseisfine' - ] - ]); - - $buildSubject = [ - 'foo' => '123' - ]; - - $this->transactionDetailsCommandMock->expects($this->once()) - ->method('execute') - ->with($buildSubject) - ->willReturn($this->transactionResultMock); - - $this->command->execute($buildSubject); - } - - public function inReviewStatusesProvider() - { - return [ - ['FDSPendingReview'], - ['FDSAuthorizedPendingReview'] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php deleted file mode 100644 index 4cbded9764793..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php +++ /dev/null @@ -1,181 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObject::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->commandMock = $this->createMock(GatewayCommand::class); - $this->commandPoolMock = $this->createMock(CommandPoolInterface::class); - $this->searchCriteriaBuilderMock = $this->createMock(SearchCriteriaBuilder::class); - $this->transactionRepositoryMock = $this->createMock(TransactionRepositoryInterface::class); - - // The search criteria builder should return the criteria with the specified filters - $this->filterBuilderMock = $this->createMock(FilterBuilder::class); - // We aren't coupling the implementation to the test. The test only cares how the result is processed - $this->filterBuilderMock->method('setField') - ->willReturnSelf(); - $this->filterBuilderMock->method('setValue') - ->willReturnSelf(); - $searchCriteria = new SearchCriteria(); - $this->searchCriteriaBuilderMock->method('addFilters') - ->willReturnSelf(); - $this->searchCriteriaBuilderMock->method('create') - ->willReturn($searchCriteria); - // The transaction result can be customized per test to simulate different scenarios - $this->transactionsResult = $this->createMock(TransactionSearchResultInterface::class); - $this->transactionRepositoryMock->method('getList') - ->with($searchCriteria) - ->willReturn($this->transactionsResult); - - $this->strategyCommand = new CaptureStrategyCommand( - $this->commandPoolMock, - $this->transactionRepositoryMock, - $this->filterBuilderMock, - $this->searchCriteriaBuilderMock, - new SubjectReader() - ); - } - - public function testExecuteWillAuthorizeWhenNotAuthorizedAndNotCaptured() - { - $subject = ['payment' => $this->paymentDOMock]; - - // Hasn't been authorized - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn(false); - // Hasn't been captured - $this->transactionsResult->method('getTotalCount') - ->willReturn(0); - // Assert authorize command was used - $this->commandPoolMock->expects($this->once()) - ->method('get') - ->with('sale') - ->willReturn($this->commandMock); - // Assert execute was called and with correct data - $this->commandMock->expects($this->once()) - ->method('execute') - ->with($subject); - - $this->strategyCommand->execute($subject); - // Assertions are performed via mock expects above - } - - public function testExecuteWillAuthorizeAndCaptureWhenAlreadyCaptured() - { - $subject = ['payment' => $this->paymentDOMock]; - - // Already authorized - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn(true); - // And already captured - $this->transactionsResult->method('getTotalCount') - ->willReturn(1); - // Assert authorize command was used - $this->commandPoolMock->expects($this->once()) - ->method('get') - ->with('settle') - ->willReturn($this->commandMock); - // Assert execute was called and with correct data - $this->commandMock->expects($this->once()) - ->method('execute') - ->with($subject); - - $this->strategyCommand->execute($subject); - // Assertions are performed via mock expects above - } - - public function testExecuteWillCaptureWhenAlreadyAuthorizedButNotCaptured() - { - $subject = ['payment' => $this->paymentDOMock]; - - // Was already authorized - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn(true); - // But, hasn't been captured - $this->transactionsResult->method('getTotalCount') - ->willReturn(0); - // Assert authorize command was used - $this->commandPoolMock->expects($this->once()) - ->method('get') - ->with('settle') - ->willReturn($this->commandMock); - // Assert execute was called and with correct data - $this->commandMock->expects($this->once()) - ->method('execute') - ->with($subject); - - $this->strategyCommand->execute($subject); - // Assertions are performed via mock expects above - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/FetchTransactionInfoCommandTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/FetchTransactionInfoCommandTest.php deleted file mode 100644 index 757500c7e50eb..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/FetchTransactionInfoCommandTest.php +++ /dev/null @@ -1,132 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObject::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->configMock = $this->createMock(Config::class); - $this->configMock->method('getTransactionInfoSyncKeys') - ->willReturn(['foo', 'bar']); - $orderMock = $this->createMock(Order::class); - $this->paymentDOMock->method('getOrder') - ->willReturn($orderMock); - $this->transactionDetailsCommandMock = $this->createMock(CommandInterface::class); - $this->transactionResultMock = $this->createMock(ResultInterface::class); - $this->commandPoolMock = $this->createMock(CommandPoolInterface::class); - $this->handlerMock = $this->createMock(HandlerInterface::class); - $this->command = new FetchTransactionInfoCommand( - $this->commandPoolMock, - new SubjectReader(), - $this->configMock, - $this->handlerMock - ); - } - - public function testCommandWillMarkTransactionAsApprovedWhenNotVoid() - { - $response = [ - 'transaction' => [ - 'transactionStatus' => 'authorizedPendingCapture', - 'foo' => 'abc', - 'bar' => 'cba', - 'dontreturnme' => 'justdont' - ] - ]; - - $this->commandPoolMock->method('get') - ->willReturnMap([ - ['get_transaction_details', $this->transactionDetailsCommandMock], - ]); - - $this->transactionResultMock->method('get') - ->willReturn($response); - - $buildSubject = [ - 'payment' => $this->paymentDOMock - ]; - - $this->transactionDetailsCommandMock->expects($this->once()) - ->method('execute') - ->with($buildSubject) - ->willReturn($this->transactionResultMock); - - $this->handlerMock->expects($this->once()) - ->method('handle') - ->with($buildSubject, $response) - ->willReturn($this->transactionResultMock); - - $result = $this->command->execute($buildSubject); - - $expected = [ - 'foo' => 'abc', - 'bar' => 'cba' - ]; - - $this->assertSame($expected, $result); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/GatewayQueryCommandTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/GatewayQueryCommandTest.php deleted file mode 100644 index e37db34936385..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/GatewayQueryCommandTest.php +++ /dev/null @@ -1,196 +0,0 @@ -requestBuilderMock = $this->createMock(BuilderInterface::class); - $this->transferFactoryMock = $this->createMock(TransferFactoryInterface::class); - $this->transferMock = $this->createMock(TransferInterface::class); - $this->clientMock = $this->createMock(ClientInterface::class); - $this->loggerMock = $this->createMock(LoggerInterface::class); - $this->validatorMock = $this->createMock(ValidatorInterface::class); - - $this->command = new GatewayQueryCommand( - $this->requestBuilderMock, - $this->transferFactoryMock, - $this->clientMock, - $this->loggerMock, - $this->validatorMock - ); - } - - public function testNormalExecution() - { - $buildSubject = [ - 'foo' => '123' - ]; - - $request = [ - 'bar' => '321' - ]; - - $response = [ - 'transaction' => [ - 'transactionType' => 'foo', - 'transactionStatus' => 'bar', - 'responseCode' => 'baz' - ] - ]; - - $validationSubject = $buildSubject; - $validationSubject['response'] = $response; - - $this->requestBuilderMock->method('build') - ->with($buildSubject) - ->willReturn($request); - - $this->transferFactoryMock->method('create') - ->with($request) - ->willReturn($this->transferMock); - - $this->clientMock->method('placeRequest') - ->with($this->transferMock) - ->willReturn($response); - - $this->validatorMock->method('validate') - ->with($validationSubject) - ->willReturn(new Result(true)); - - $result = $this->command->execute($buildSubject); - - $this->assertInstanceOf(ArrayResult::class, $result); - $this->assertEquals($response, $result->get()); - } - - /** - * @expectedExceptionMessage There was an error while trying to process the request. - * @expectedException \Magento\Payment\Gateway\Command\CommandException - */ - public function testExceptionIsThrownAndLoggedWhenRequestFails() - { - $buildSubject = [ - 'foo' => '123' - ]; - - $request = [ - 'bar' => '321' - ]; - - $this->requestBuilderMock->method('build') - ->with($buildSubject) - ->willReturn($request); - - $this->transferFactoryMock->method('create') - ->with($request) - ->willReturn($this->transferMock); - - $e = new \Exception('foobar'); - - $this->clientMock->method('placeRequest') - ->with($this->transferMock) - ->willThrowException($e); - - // assert the exception is logged - $this->loggerMock->expects($this->once()) - ->method('critical') - ->with($e); - - $this->command->execute($buildSubject); - } - /** - * @expectedExceptionMessage There was an error while trying to process the request. - * @expectedException \Magento\Payment\Gateway\Command\CommandException - */ - public function testExceptionIsThrownWhenResponseIsInvalid() - { - $buildSubject = [ - 'foo' => '123' - ]; - - $request = [ - 'bar' => '321' - ]; - - $response = [ - 'baz' => '456' - ]; - - $validationSubject = $buildSubject; - $validationSubject['response'] = $response; - - $this->requestBuilderMock->method('build') - ->with($buildSubject) - ->willReturn($request); - - $this->transferFactoryMock->method('create') - ->with($request) - ->willReturn($this->transferMock); - - $this->clientMock->method('placeRequest') - ->with($this->transferMock) - ->willReturn($response); - - $this->validatorMock->method('validate') - ->with($validationSubject) - ->willReturn(new Result(false)); - - $this->command->execute($buildSubject); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/RefundTransactionStrategyCommandTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/RefundTransactionStrategyCommandTest.php deleted file mode 100644 index 79477b06e0e6c..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Command/RefundTransactionStrategyCommandTest.php +++ /dev/null @@ -1,225 +0,0 @@ -transactionDetailsCommandMock = $this->createMock(CommandInterface::class); - $this->commandMock = $this->createMock(CommandInterface::class); - $this->transactionResultMock = $this->createMock(ResultInterface::class); - $this->commandPoolMock = $this->createMock(CommandPoolInterface::class); - $this->command = new RefundTransactionStrategyCommand( - $this->commandPoolMock, - new SubjectReader() - ); - } - - public function testCommandWillVoidWhenTransactionIsPendingSettlement() - { - // Assert command is executed - $this->commandMock->expects($this->once()) - ->method('execute'); - - $this->commandPoolMock->method('get') - ->willReturnMap( - [ - [ - 'get_transaction_details', - $this->transactionDetailsCommandMock - ], - [ - 'void', - $this->commandMock - ] - ] - ); - - $this->transactionResultMock->method('get') - ->willReturn( - [ - 'transaction' => [ - 'transactionStatus' => 'capturedPendingSettlement', - 'authAmount' => '20.19', - ] - ] - ); - - $buildSubject = [ - 'foo' => '123', - 'amount' => '20.19', - ]; - - $this->transactionDetailsCommandMock->expects($this->once()) - ->method('execute') - ->with($buildSubject) - ->willReturn($this->transactionResultMock); - - $this->command->execute($buildSubject); - } - - /** - * @expectedException \Magento\Payment\Gateway\Command\CommandException - * @expectedExceptionMessage The transaction has not been settled, a partial refund is not yet available. - */ - public function testCommandWillThrowExceptionWhenVoidTransactionIsPartial() - { - // Assert command is executed - $this->commandMock->expects($this->never()) - ->method('execute'); - - $this->commandPoolMock->method('get') - ->willReturnMap( - [ - [ - 'get_transaction_details', - $this->transactionDetailsCommandMock - ], - ] - ); - - $this->transactionResultMock->method('get') - ->willReturn( - [ - 'transaction' => [ - 'transactionStatus' => 'capturedPendingSettlement', - 'authAmount' => '20.19', - ] - ] - ); - - $buildSubject = [ - 'foo' => '123', - 'amount' => '10.19', - ]; - - $this->transactionDetailsCommandMock->expects($this->once()) - ->method('execute') - ->with($buildSubject) - ->willReturn($this->transactionResultMock); - - $this->command->execute($buildSubject); - } - - public function testCommandWillRefundWhenTransactionIsSettled() - { - // Assert command is executed - $this->commandMock->expects($this->once()) - ->method('execute'); - - $this->commandPoolMock->method('get') - ->willReturnMap( - [ - [ - 'get_transaction_details', - $this->transactionDetailsCommandMock - ], - [ - 'refund_settled', - $this->commandMock - ] - ] - ); - - $this->transactionResultMock->method('get') - ->willReturn( - [ - 'transaction' => [ - 'transactionStatus' => 'settledSuccessfully' - ] - ] - ); - - $buildSubject = [ - 'foo' => '123' - ]; - - $this->transactionDetailsCommandMock->expects($this->once()) - ->method('execute') - ->with($buildSubject) - ->willReturn($this->transactionResultMock); - - $this->command->execute($buildSubject); - } - - /** - * @expectedException \Magento\Payment\Gateway\Command\CommandException - * @expectedExceptionMessage This transaction cannot be refunded with its current status. - */ - public function testCommandWillThrowExceptionWhenTransactionIsInInvalidState() - { - // Assert command is never executed - $this->commandMock->expects($this->never()) - ->method('execute'); - - $this->commandPoolMock->method('get') - ->willReturnMap( - [ - [ - 'get_transaction_details', - $this->transactionDetailsCommandMock - ], - ] - ); - - $this->transactionResultMock->method('get') - ->willReturn( - [ - 'transaction' => [ - 'transactionStatus' => 'somethingIsWrong' - ] - ] - ); - - $buildSubject = [ - 'foo' => '123' - ]; - - $this->transactionDetailsCommandMock->expects($this->once()) - ->method('execute') - ->with($buildSubject) - ->willReturn($this->transactionResultMock); - - $this->command->execute($buildSubject); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/ConfigTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/ConfigTest.php deleted file mode 100644 index 646ad4f195b9d..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/ConfigTest.php +++ /dev/null @@ -1,136 +0,0 @@ -scopeConfigMock = $this->createMock(ScopeConfigInterface::class); - - $objectManager = new ObjectManager($this); - $this->model = $objectManager->getObject( - Config::class, - [ - 'scopeConfig' => $this->scopeConfigMock, - 'methodCode' => Config::METHOD, - ] - ); - } - - /** - * @param $getterName - * @param $configField - * @param $configValue - * @param $expectedValue - * @dataProvider configMapProvider - */ - public function testConfigGetters($getterName, $configField, $configValue, $expectedValue) - { - $this->scopeConfigMock->method('getValue') - ->with($this->getPath($configField), ScopeInterface::SCOPE_STORE, 123) - ->willReturn($configValue); - $this->assertEquals($expectedValue, $this->model->{$getterName}(123)); - } - - /** - * @dataProvider environmentUrlProvider - * @param $environment - * @param $expectedUrl - */ - public function testGetApiUrl($environment, $expectedUrl) - { - $this->scopeConfigMock->method('getValue') - ->with($this->getPath('environment'), ScopeInterface::SCOPE_STORE, 123) - ->willReturn($environment); - $this->assertEquals($expectedUrl, $this->model->getApiUrl(123)); - } - - /** - * @dataProvider environmentSolutionProvider - * @param $environment - * @param $expectedSolution - */ - public function testGetSolutionIdSandbox($environment, $expectedSolution) - { - $this->scopeConfigMock->method('getValue') - ->with($this->getPath('environment'), ScopeInterface::SCOPE_STORE, 123) - ->willReturn($environment); - $this->assertEquals($expectedSolution, $this->model->getSolutionId(123)); - } - - /** - * @return array - */ - public function configMapProvider() - { - return [ - ['getLoginId', 'login', 'username', 'username'], - ['getEnvironment', 'environment', 'production', 'production'], - ['getClientKey', 'public_client_key', 'abc', 'abc'], - ['getTransactionKey', 'trans_key', 'password', 'password'], - ['getLegacyTransactionHash', 'trans_md5', 'abc123', 'abc123'], - ['getTransactionSignatureKey', 'trans_signature_key', 'abc123', 'abc123'], - ['getPaymentAction', 'payment_action', 'authorize', 'authorize'], - ['shouldEmailCustomer', 'email_customer', true, true], - ['isCvvEnabled', 'cvv_enabled', true, true], - ['getAdditionalInfoKeys', 'paymentInfoKeys', 'a,b,c', ['a', 'b', 'c']], - ['getTransactionInfoSyncKeys', 'transactionSyncKeys', 'a,b,c', ['a', 'b', 'c']], - ]; - } - - /** - * @return array - */ - public function environmentUrlProvider() - { - return [ - ['sandbox', 'https://apitest.authorize.net/xml/v1/request.api'], - ['production', 'https://api.authorize.net/xml/v1/request.api'], - ]; - } - - /** - * @return array - */ - public function environmentSolutionProvider() - { - return [ - ['sandbox', 'AAA102993'], - ['production', 'AAA175350'], - ]; - } - - /** - * Return config path - * - * @param string $field - * @return string - */ - private function getPath($field) - { - return sprintf(Config::DEFAULT_PATH_PATTERN, Config::METHOD, $field); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/ClientTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/ClientTest.php deleted file mode 100644 index 4086195ff4c95..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/ClientTest.php +++ /dev/null @@ -1,218 +0,0 @@ -objectManager = new ObjectManager($this); - $this->paymentLogger = $this->createMock(Logger::class); - $this->httpClientFactory = $this->createMock(ZendClientFactory::class); - $this->httpClient = $this->createMock(Zend_Http_Client::class); - $this->httpResponse = $this->createMock(Zend_Http_Response::class); - $this->httpClientFactory->method('create')->will($this->returnValue($this->httpClient)); - $this->httpClient->method('request') - ->willReturn($this->httpResponse); - /** @var MockObject $logger */ - $this->logger = $this->createMock(LoggerInterface::class); - } - - public function testCanSendRequest() - { - // Assert the raw data was set on the client - $this->httpClient->expects($this->once()) - ->method('setRawData') - ->with( - '{"doSomeThing":{"foobar":"baz"}}', - 'application/json' - ); - - $request = [ - 'payload_type' => 'doSomeThing', - 'foobar' => 'baz' - ]; - // Authorize.net returns a BOM and refuses to fix it - $response = pack('CCC', 0xef, 0xbb, 0xbf) . '{"foo":{"bar":"baz"}}'; - - $this->httpResponse->method('getBody') - ->willReturn($response); - - // Assert the logger was given the data - $this->paymentLogger->expects($this->once()) - ->method('debug') - ->with(['request' => $request, 'response' => '{"foo":{"bar":"baz"}}']); - - /** - * @var $apiClient Client - */ - $apiClient = $this->objectManager->getObject(Client::class, [ - 'httpClientFactory' => $this->httpClientFactory, - 'paymentLogger' => $this->paymentLogger, - 'json' => new Json() - ]); - - $result = $apiClient->placeRequest($this->getTransferObjectMock($request)); - - $this->assertSame('baz', $result['foo']['bar']); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage Something went wrong in the payment gateway. - */ - public function testExceptionIsThrownWhenEmptyResponseIsReceived() - { - // Assert the client has the raw data set - $this->httpClient->expects($this->once()) - ->method('setRawData') - ->with( - '{"doSomeThing":{"foobar":"baz"}}', - 'application/json' - ); - - $this->httpResponse->method('getBody') - ->willReturn(''); - - // Assert the exception is given to the logger - $this->logger->expects($this->once()) - ->method('critical') - ->with($this->callback(function ($e) { - return $e instanceof \Exception - && $e->getMessage() === 'Invalid JSON was returned by the gateway'; - })); - - $request = [ - 'payload_type' => 'doSomeThing', - 'foobar' => 'baz' - ]; - - // Assert the logger was given the data - $this->paymentLogger->expects($this->once()) - ->method('debug') - ->with(['request' => $request, 'response' => '']); - - /** - * @var $apiClient Client - */ - $apiClient = $this->objectManager->getObject(Client::class, [ - 'httpClientFactory' => $this->httpClientFactory, - 'paymentLogger' => $this->paymentLogger, - 'logger' => $this->logger, - 'json' => new Json() - ]); - - $apiClient->placeRequest($this->getTransferObjectMock($request)); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage Something went wrong in the payment gateway. - */ - public function testExceptionIsThrownWhenInvalidResponseIsReceived() - { - // Assert the client was given the raw data - $this->httpClient->expects($this->once()) - ->method('setRawData') - ->with( - '{"doSomeThing":{"foobar":"baz"}}', - 'application/json' - ); - - $this->httpResponse->method('getBody') - ->willReturn('bad'); - - $request = [ - 'payload_type' => 'doSomeThing', - 'foobar' => 'baz' - ]; - - // Assert the logger was given the data - $this->paymentLogger->expects($this->once()) - ->method('debug') - ->with(['request' => $request, 'response' => 'bad']); - - // Assert the exception was given to the logger - $this->logger->expects($this->once()) - ->method('critical') - ->with($this->callback(function ($e) { - return $e instanceof \Exception - && $e->getMessage() === 'Invalid JSON was returned by the gateway'; - })); - - /** - * @var $apiClient Client - */ - $apiClient = $this->objectManager->getObject(Client::class, [ - 'httpClientFactory' => $this->httpClientFactory, - 'paymentLogger' => $this->paymentLogger, - 'logger' => $this->logger, - 'json' => new Json() - ]); - - $apiClient->placeRequest($this->getTransferObjectMock($request)); - } - - /** - * Creates mock object for TransferInterface. - * - * @return TransferInterface|MockObject - */ - private function getTransferObjectMock(array $data) - { - $transferObjectMock = $this->createMock(TransferInterface::class); - $transferObjectMock->method('getBody') - ->willReturn($data); - - return $transferObjectMock; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/Payload/Filter/RemoveFieldsFilterTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/Payload/Filter/RemoveFieldsFilterTest.php deleted file mode 100644 index bcc6279f5b1fe..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/Payload/Filter/RemoveFieldsFilterTest.php +++ /dev/null @@ -1,36 +0,0 @@ -filter([ - 'some' => 123, - 'data' => 321, - 'foo' => 'to', - 'filter' => ['blah'], - 'bar' => 'fields from' - ]); - - $expected = [ - 'some' => 123, - 'data' => 321, - 'filter' => ['blah'], - ]; - - $this->assertEquals($expected, $actual); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/TransferFactoryTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/TransferFactoryTest.php deleted file mode 100644 index 954fd9782bd3f..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Http/TransferFactoryTest.php +++ /dev/null @@ -1,73 +0,0 @@ -transferBuilder = $this->createMock(TransferBuilder::class); - $this->transferMock = $this->createMock(TransferInterface::class); - $this->filterMock = $this->createMock(RemoveFieldsFilter::class); - - $this->transferFactory = new TransferFactory( - $this->transferBuilder, - [$this->filterMock] - ); - } - - public function testCreate() - { - $request = ['data1', 'data2']; - - // Assert the filter was created - $this->filterMock->expects($this->once()) - ->method('filter') - ->with($request) - ->willReturn($request); - - // Assert the body of the transfer was set - $this->transferBuilder->expects($this->once()) - ->method('setBody') - ->with($request) - ->willReturnSelf(); - - $this->transferBuilder->method('build') - ->willReturn($this->transferMock); - - $this->assertEquals($this->transferMock, $this->transferFactory->create($request)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AcceptFdsDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AcceptFdsDataBuilderTest.php deleted file mode 100644 index 00bb7ee84f98b..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AcceptFdsDataBuilderTest.php +++ /dev/null @@ -1,70 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->orderMock = $this->createMock(Order::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new AcceptFdsDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $transactionMock = $this->createMock(Transaction::class); - - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn($transactionMock); - - $transactionMock->method('getTxnId') - ->willReturn('foo'); - - $expected = [ - 'heldTransactionRequest' => [ - 'action' => 'approve', - 'refTransId' => 'foo' - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AddressDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AddressDataBuilderTest.php deleted file mode 100644 index 84c2f19040e16..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AddressDataBuilderTest.php +++ /dev/null @@ -1,138 +0,0 @@ - [ - 'method' => 'getFirstname', - 'sampleData' => 'John' - ], - 'lastName' => [ - 'method' => 'getLastname', - 'sampleData' => 'Doe' - ], - 'company' => [ - 'method' => 'getCompany', - 'sampleData' => 'Magento' - ], - 'address' => [ - 'method' => 'getStreetLine1', - 'sampleData' => '11501 Domain Dr' - ], - 'city' => [ - 'method' => 'getCity', - 'sampleData' => 'Austin' - ], - 'state' => [ - 'method' => 'getRegionCode', - 'sampleData' => 'TX' - ], - 'zip' => [ - 'method' => 'getPostcode', - 'sampleData' => '78758' - ], - 'country' => [ - 'method' => 'getCountryId', - 'sampleData' => 'US' - ], - ]; - - protected function setUp() - { - $this->paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - $this->paymentDOMock->method('getOrder') - ->willReturn($this->orderMock); - - $this->builder = new AddressDataBuilder(new SubjectReader()); - } - - public function testBuildWithBothAddresses() - { - $billingAddress = $this->createAddressMock('billing'); - $shippingAddress = $this->createAddressMock('shipping'); - $this->orderMock->method('getBillingAddress') - ->willReturn($billingAddress); - $this->orderMock->method('getShippingAddress') - ->willReturn($shippingAddress); - $this->orderMock->method('getRemoteIp') - ->willReturn('abc'); - - $buildSubject = [ - 'payment' => $this->paymentDOMock - ]; - - $result = $this->builder->build($buildSubject); - - $this->validateAddressData($result['transactionRequest']['billTo'], 'billing'); - $this->validateAddressData($result['transactionRequest']['shipTo'], 'shipping'); - $this->assertEquals('abc', $result['transactionRequest']['customerIP']); - } - - /** - * @param $responseData - * @param $addressPrefix - */ - private function validateAddressData($responseData, $addressPrefix) - { - foreach ($this->mockAddressData as $fieldValue => $field) { - $this->assertEquals($addressPrefix . $field['sampleData'], $responseData[$fieldValue]); - } - } - - /** - * @param $prefix - * - * @return \PHPUnit\Framework\MockObject\MockObject - */ - private function createAddressMock($prefix) - { - $addressAdapterMock = $this->createMock(AddressAdapterInterface::class); - - foreach ($this->mockAddressData as $field) { - $addressAdapterMock->method($field['method']) - ->willReturn($prefix . $field['sampleData']); - } - - return $addressAdapterMock; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AmountDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AmountDataBuilderTest.php deleted file mode 100644 index 9da0139302a30..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AmountDataBuilderTest.php +++ /dev/null @@ -1,42 +0,0 @@ -builder = new AmountDataBuilder( - new SubjectReader() - ); - } - - public function testBuild() - { - $expected = [ - 'transactionRequest' => [ - 'amount' => '123.45', - ] - ]; - - $buildSubject = [ - 'amount' => 123.45 - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AuthenticationDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AuthenticationDataBuilderTest.php deleted file mode 100644 index e9588e51b0fc8..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AuthenticationDataBuilderTest.php +++ /dev/null @@ -1,78 +0,0 @@ -configMock = $this->createMock(Config::class); - $this->paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - /** @var MockObject|SubjectReader subjectReaderMock */ - $this->subjectReaderMock = $this->createMock(SubjectReader::class); - - $this->builder = new AuthenticationDataBuilder($this->subjectReaderMock, $this->configMock); - } - - public function testBuild() - { - $this->configMock->method('getLoginId') - ->willReturn('myloginid'); - $this->configMock->method('getTransactionKey') - ->willReturn('mytransactionkey'); - - $expected = [ - 'merchantAuthentication' => [ - 'name' => 'myloginid', - 'transactionKey' => 'mytransactionkey' - ] - ]; - - $buildSubject = []; - - $this->subjectReaderMock->method('readStoreId') - ->with($buildSubject) - ->willReturn(123); - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AuthorizationDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AuthorizationDataBuilderTest.php deleted file mode 100644 index 438d681a2b5b2..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/AuthorizationDataBuilderTest.php +++ /dev/null @@ -1,70 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->passthroughData = new PassthroughDataObject(); - - $this->builder = new AuthorizeDataBuilder( - new SubjectReader(), - $this->passthroughData - ); - } - - public function testBuildWillAddTransactionType() - { - $expected = [ - 'transactionRequest' => [ - 'transactionType' => 'authOnlyTransaction' - ] - ]; - - $buildSubject = [ - 'store_id' => 123, - 'payment' => $this->paymentDOMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - $this->assertEquals('authOnlyTransaction', $this->passthroughData->getData('transactionType')); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php deleted file mode 100644 index 537a685f1ff7f..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php +++ /dev/null @@ -1,77 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->passthroughData = new PassthroughDataObject(); - - $this->builder = new CaptureDataBuilder( - new SubjectReader(), - $this->passthroughData - ); - } - - public function testBuildWillCaptureWhenAuthorizeTransactionExists() - { - $transactionMock = $this->createMock(Payment\Transaction::class); - $transactionMock->method('getAdditionalInformation') - ->with('real_transaction_id') - ->willReturn('prevtrans'); - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn($transactionMock); - - $expected = [ - 'transactionRequest' => [ - 'transactionType' => 'priorAuthCaptureTransaction', - 'refTransId' => 'prevtrans' - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - $this->assertEquals('priorAuthCaptureTransaction', $this->passthroughData->getData('transactionType')); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CustomSettingsBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CustomSettingsBuilderTest.php deleted file mode 100644 index be7dd7eca1761..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CustomSettingsBuilderTest.php +++ /dev/null @@ -1,74 +0,0 @@ -configMock = $this->createMock(Config::class); - /** @var MockObject|SubjectReader subjectReaderMock */ - $this->subjectReaderMock = $this->createMock(SubjectReader::class); - $this->subjectReaderMock->method('readStoreId') - ->willReturn('123'); - - $this->builder = new CustomSettingsBuilder($this->subjectReaderMock, $this->configMock); - } - - public function testBuildWithEmailCustomerDisabled() - { - $this->configMock->method('shouldEmailCustomer') - ->with('123') - ->willReturn(false); - - $this->assertEquals([], $this->builder->build([])); - } - - public function testBuildWithEmailCustomerEnabled() - { - $this->configMock->method('shouldEmailCustomer') - ->with('123') - ->willReturn(true); - - $expected = [ - 'transactionRequest' => [ - 'transactionSettings' => [ - 'setting' => [ - [ - 'settingName' => 'emailCustomer', - 'settingValue' => 'true' - ] - ] - ] - ] - ]; - - $this->assertEquals($expected, $this->builder->build([])); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CustomerDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CustomerDataBuilderTest.php deleted file mode 100644 index 7c9116cad54b1..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/CustomerDataBuilderTest.php +++ /dev/null @@ -1,79 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - $this->paymentDOMock->method('getOrder') - ->willReturn($this->orderMock); - - $this->builder = new CustomerDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $addressAdapterMock = $this->createMock(AddressAdapterInterface::class); - $addressAdapterMock->method('getEmail') - ->willReturn('foo@bar.com'); - $this->orderMock->method('getBillingAddress') - ->willReturn($addressAdapterMock); - $this->orderMock->method('getCustomerId') - ->willReturn('123'); - - $expected = [ - 'transactionRequest' => [ - 'customer' => [ - 'id' => '123', - 'email' => 'foo@bar.com' - ] - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/OrderDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/OrderDataBuilderTest.php deleted file mode 100644 index d66421d48ca8b..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/OrderDataBuilderTest.php +++ /dev/null @@ -1,74 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - $this->paymentDOMock->method('getOrder') - ->willReturn($this->orderMock); - - $this->builder = new OrderDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $this->orderMock->method('getOrderIncrementId') - ->willReturn('10000015'); - - $expected = [ - 'transactionRequest' => [ - 'order' => [ - 'invoiceNumber' => '10000015' - ] - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - 'order' => $this->orderMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PassthroughDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PassthroughDataBuilderTest.php deleted file mode 100644 index f4c5f56efe890..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PassthroughDataBuilderTest.php +++ /dev/null @@ -1,52 +0,0 @@ - 'bar', - 'baz' => 'bash' - ]); - $builder = new PassthroughDataBuilder($passthroughData); - - $expected = [ - 'transactionRequest' => [ - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'foo', - 'value' => 'bar' - ], - [ - 'name' => 'baz', - 'value' => 'bash' - ], - ] - ] - ] - ]; - - $this->assertEquals($expected, $builder->build([])); - } - - public function testBuildWithNoData() - { - $passthroughData = new PassthroughDataObject(); - $builder = new PassthroughDataBuilder($passthroughData); - $expected = []; - - $this->assertEquals($expected, $builder->build([])); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php deleted file mode 100644 index cf3842b8947bb..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php +++ /dev/null @@ -1,72 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->orderMock = $this->createMock(Order::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new PaymentDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $this->paymentMock->method('getAdditionalInformation') - ->willReturnMap([ - ['opaqueDataDescriptor', 'foo'], - ['opaqueDataValue', 'bar'] - ]); - - $expected = [ - 'transactionRequest' => [ - 'payment' => [ - 'opaqueData' => [ - 'dataDescriptor' => 'foo', - 'dataValue' => 'bar' - ] - ] - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - 'amount' => 123.45 - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PoDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PoDataBuilderTest.php deleted file mode 100644 index 97b51c1e1807c..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/PoDataBuilderTest.php +++ /dev/null @@ -1,61 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new PoDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $this->paymentMock->method('getPoNumber') - ->willReturn('abc'); - - $expected = [ - 'transactionRequest' => [ - 'poNumber' => 'abc' - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - ]; - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundPaymentDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundPaymentDataBuilderTest.php deleted file mode 100644 index c1879b3df83a3..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundPaymentDataBuilderTest.php +++ /dev/null @@ -1,70 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new RefundPaymentDataBuilder( - new SubjectReader() - ); - } - - public function testBuild() - { - $this->paymentMock->method('getAdditionalInformation') - ->with('ccLast4') - ->willReturn('1111'); - - $expected = [ - 'transactionRequest' => [ - 'payment' => [ - 'creditCard' => [ - 'cardNumber' => '1111', - 'expirationDate' => 'XXXX' - ] - ] - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - 'amount' => 123.45 - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundReferenceTransactionDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundReferenceTransactionDataBuilderTest.php deleted file mode 100644 index cf1803005acee..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundReferenceTransactionDataBuilderTest.php +++ /dev/null @@ -1,69 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->orderMock = $this->createMock(Order::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new RefundReferenceTransactionDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $transactionMock = $this->createMock(Transaction::class); - - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn($transactionMock); - - $transactionMock->method('getParentTxnId') - ->willReturn('foo'); - - $expected = [ - 'transactionRequest' => [ - 'refTransId' => 'foo' - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundTransactionTypeDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundTransactionTypeDataBuilderTest.php deleted file mode 100644 index 4e0f5f75fb944..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RefundTransactionTypeDataBuilderTest.php +++ /dev/null @@ -1,30 +0,0 @@ - [ - 'transactionType' => self::REQUEST_TYPE_REFUND - ] - ]; - - $this->assertEquals($expected, $builder->build([])); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RequestTypeBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RequestTypeBuilderTest.php deleted file mode 100644 index cb03dfc3dac5e..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/RequestTypeBuilderTest.php +++ /dev/null @@ -1,36 +0,0 @@ -builder = new RequestTypeBuilder('foo'); - } - - public function testBuild() - { - $expected = [ - 'payload_type' => 'foo' - ]; - - $buildSubject = []; - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/SaleDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/SaleDataBuilderTest.php deleted file mode 100644 index 407b9bc85a2c5..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/SaleDataBuilderTest.php +++ /dev/null @@ -1,70 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->passthroughData = new PassthroughDataObject(); - - $this->builder = new SaleDataBuilder( - new SubjectReader(), - $this->passthroughData - ); - } - - public function testBuildWillAddTransactionType() - { - $expected = [ - 'transactionRequest' => [ - 'transactionType' => 'authCaptureTransaction' - ] - ]; - - $buildSubject = [ - 'store_id' => 123, - 'payment' => $this->paymentDOMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - $this->assertEquals('authCaptureTransaction', $this->passthroughData->getData('transactionType')); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/ShippingDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/ShippingDataBuilderTest.php deleted file mode 100644 index d6525e610a285..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/ShippingDataBuilderTest.php +++ /dev/null @@ -1,75 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->orderMock = $this->createMock(Order::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->paymentDOMock->method('getOrder') - ->willReturn($this->orderMock); - - $this->builder = new ShippingDataBuilder( - new SubjectReader() - ); - } - - public function testBuild() - { - $this->orderMock->method('getBaseShippingAmount') - ->willReturn('43.12'); - - $expected = [ - 'transactionRequest' => [ - 'shipping' => [ - 'amount' => '43.12' - ] - ] - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - 'order' => $this->orderMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/SolutionDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/SolutionDataBuilderTest.php deleted file mode 100644 index 1b06546c2ea8f..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/SolutionDataBuilderTest.php +++ /dev/null @@ -1,75 +0,0 @@ -configMock = $this->createMock(Config::class); - $this->paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - /** @var MockObject|SubjectReader subjectReaderMock */ - $this->subjectReaderMock = $this->createMock(SubjectReader::class); - - $this->builder = new SolutionDataBuilder($this->subjectReaderMock, $this->configMock); - } - - public function testBuild() - { - $this->subjectReaderMock->method('readStoreId') - ->willReturn('123'); - $this->configMock->method('getSolutionId') - ->with('123') - ->willReturn('solutionid'); - - $expected = [ - 'transactionRequest' => [ - 'solution' => [ - 'id' => 'solutionid', - ] - ] - ]; - - $buildSubject = []; - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/StoreConfigBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/StoreConfigBuilderTest.php deleted file mode 100644 index 2ed0cb13ed624..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/StoreConfigBuilderTest.php +++ /dev/null @@ -1,68 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(InfoInterface::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - $this->paymentDOMock->method('getOrder') - ->willReturn($this->orderMock); - - $this->builder = new StoreConfigBuilder(new SubjectReader()); - } - - public function testBuild() - { - $this->orderMock->method('getStoreID') - ->willReturn(123); - - $expected = [ - 'store_id' => 123 - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - ]; - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/TransactionDetailsDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/TransactionDetailsDataBuilderTest.php deleted file mode 100644 index 03c036c027147..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/TransactionDetailsDataBuilderTest.php +++ /dev/null @@ -1,89 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->orderMock = $this->createMock(Order::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new TransactionDetailsDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $transactionMock = $this->createMock(Transaction::class); - - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn($transactionMock); - - $transactionMock->method('getParentTxnId') - ->willReturn('foo'); - - $expected = [ - 'transId' => 'foo' - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } - - public function testBuildWithIncludedTransactionId() - { - $transactionMock = $this->createMock(Transaction::class); - - $this->paymentMock->expects($this->never()) - ->method('getAuthorizationTransaction'); - - $transactionMock->expects($this->never()) - ->method('getParentTxnId'); - - $expected = [ - 'transId' => 'foo' - ]; - - $buildSubject = [ - 'payment' => $this->paymentDOMock, - 'transactionId' => 'foo' - ]; - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/VoidDataBuilderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/VoidDataBuilderTest.php deleted file mode 100644 index 84460a1c744b9..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Request/VoidDataBuilderTest.php +++ /dev/null @@ -1,68 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new VoidDataBuilder(new SubjectReader()); - } - - public function testBuild() - { - $transactionMock = $this->createMock(Transaction::class); - $this->paymentMock->method('getAuthorizationTransaction') - ->willReturn($transactionMock); - $transactionMock->method('getParentTxnId') - ->willReturn('myref'); - - $buildSubject = [ - 'payment' => $this->paymentDOMock - ]; - - $expected = [ - 'transactionRequest' => [ - 'transactionType' => self::REQUEST_TYPE_VOID, - 'refTransId' => 'myref', - ] - ]; - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/CloseParentTransactionHandlerTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/CloseParentTransactionHandlerTest.php deleted file mode 100644 index e9929c631eb15..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/CloseParentTransactionHandlerTest.php +++ /dev/null @@ -1,62 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->handler = new CloseParentTransactionHandler(new SubjectReader()); - } - - public function testHandleClosesTransactionByDefault() - { - $subject = [ - 'payment' => $this->paymentDOMock - ]; - $response = [ - 'transactionResponse' => [] - ]; - - // Assert the parent transaction i closed - $this->paymentMock->expects($this->once()) - ->method('setShouldCloseParentTransaction') - ->with(true); - - $this->handler->handle($subject, $response); - // Assertions are via mock expects above - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/CloseTransactionHandlerTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/CloseTransactionHandlerTest.php deleted file mode 100644 index a7093f0dac889..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/CloseTransactionHandlerTest.php +++ /dev/null @@ -1,62 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->handler = new CloseTransactionHandler(new SubjectReader()); - } - - public function testHandleClosesTransactionByDefault() - { - $subject = [ - 'payment' => $this->paymentDOMock - ]; - $response = [ - 'transactionResponse' => [] - ]; - - // Assert the transaction is closed - $this->paymentMock->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(true); - - $this->handler->handle($subject, $response); - // Assertions are via mock expects above - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/PaymentResponseHandlerTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/PaymentResponseHandlerTest.php deleted file mode 100644 index d051c7d2910a5..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/PaymentResponseHandlerTest.php +++ /dev/null @@ -1,112 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new PaymentResponseHandler(new SubjectReader()); - } - - public function testHandleDefaultResponse() - { - $this->paymentMock->method('getAdditionalInformation') - ->with('ccLast4') - ->willReturn('1234'); - // Assert the avs code is saved - $this->paymentMock->expects($this->once()) - ->method('setCcAvsStatus') - ->with('avshurray'); - $this->paymentMock->expects($this->once()) - ->method('setCcLast4') - ->with('1234'); - $this->paymentMock->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(false); - - $response = [ - 'transactionResponse' => [ - 'avsResultCode' => 'avshurray', - 'responseCode' => self::RESPONSE_CODE_APPROVED, - ] - ]; - $subject = [ - 'payment' => $this->paymentDOMock - ]; - - $this->builder->handle($subject, $response); - // Assertions are part of mocking above - } - - public function testHandleHeldResponse() - { - // Assert the avs code is saved - $this->paymentMock->expects($this->once()) - ->method('setCcAvsStatus') - ->with('avshurray'); - $this->paymentMock->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(false); - // opaque data wasn't provided - $this->paymentMock->expects($this->never()) - ->method('setAdditionalInformation'); - // Assert the payment is flagged for review - $this->paymentMock->expects($this->once()) - ->method('setIsTransactionPending') - ->with(true) - ->willReturnSelf(); - $this->paymentMock->expects($this->once()) - ->method('setIsFraudDetected') - ->with(true); - - $response = [ - 'transactionResponse' => [ - 'avsResultCode' => 'avshurray', - 'responseCode' => self::RESPONSE_CODE_HELD, - ] - ]; - $subject = [ - 'payment' => $this->paymentDOMock - ]; - - $this->builder->handle($subject, $response); - // Assertions are part of mocking above - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/PaymentReviewStatusHandlerTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/PaymentReviewStatusHandlerTest.php deleted file mode 100644 index 197dc209ece66..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/PaymentReviewStatusHandlerTest.php +++ /dev/null @@ -1,136 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->handler = new PaymentReviewStatusHandler(new SubjectReader()); - } - - public function testApprovesPayment() - { - $subject = [ - 'payment' => $this->paymentDOMock - ]; - $response = [ - 'transaction' => [ - 'transactionStatus' => 'approvedOrSomething', - ] - ]; - - // Assert payment is handled correctly - $this->paymentMock->expects($this->exactly(2)) - ->method('setData') - ->withConsecutive( - ['is_transaction_denied', false], - ['is_transaction_approved', true] - ); - - $this->handler->handle($subject, $response); - // Assertions are via mock expects above - } - - /** - * @param string $status - * @dataProvider declinedTransactionStatusesProvider - */ - public function testDeniesPayment(string $status) - { - $subject = [ - 'payment' => $this->paymentDOMock - ]; - $response = [ - 'transaction' => [ - 'transactionStatus' => $status, - ] - ]; - - // Assert payment is handled correctly - $this->paymentMock->expects($this->exactly(2)) - ->method('setData') - ->withConsecutive( - ['is_transaction_denied', true], - ['is_transaction_approved', false] - ); - $this->handler->handle($subject, $response); - } - - /** - * @param string $status - * @dataProvider pendingTransactionStatusesProvider - */ - public function testDoesNothingWhenPending(string $status) - { - $subject = [ - 'payment' => $this->paymentDOMock - ]; - $response = [ - 'transaction' => [ - 'transactionStatus' => $status, - ] - ]; - - // Assert payment is handled correctly - $this->paymentMock->expects($this->never()) - ->method('setData'); - - $this->handler->handle($subject, $response); - } - - /** - * @return array - */ - public function pendingTransactionStatusesProvider() - { - return [ - ['FDSPendingReview'], - ['FDSAuthorizedPendingReview'] - ]; - } - - /** - * @return array - */ - public function declinedTransactionStatusesProvider() - { - return [ - ['void'], - ['declined'] - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/TransactionDetailsResponseHandlerTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/TransactionDetailsResponseHandlerTest.php deleted file mode 100644 index 016e3a1e95383..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/TransactionDetailsResponseHandlerTest.php +++ /dev/null @@ -1,82 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->configMock = $this->createMock(Config::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->handler = new TransactionDetailsResponseHandler(new SubjectReader(), $this->configMock); - } - - public function testHandle() - { - $subject = [ - 'payment' => $this->paymentDOMock, - 'store_id' => 123, - ]; - $response = [ - 'transactionResponse' => [ - 'dontsaveme' => 'dontdoti', - 'abc' => 'foobar', - ] - ]; - - // Assert the information comes from the right store config - $this->configMock->method('getAdditionalInfoKeys') - ->with(123) - ->willReturn(['abc']); - - // Assert the payment has the most recent information always set on it - $this->paymentMock->expects($this->once()) - ->method('setAdditionalInformation') - ->with('abc', 'foobar'); - // Assert the transaction has the raw details from the transaction - $this->paymentMock->expects($this->once()) - ->method('setTransactionAdditionalInfo') - ->with('raw_details_info', ['abc' => 'foobar']); - - $this->handler->handle($subject, $response); - // Assertions are via mock expects above - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/TransactionIdHandlerTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/TransactionIdHandlerTest.php deleted file mode 100644 index 710f995918495..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/TransactionIdHandlerTest.php +++ /dev/null @@ -1,92 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->builder = new TransactionIdHandler(new SubjectReader()); - } - - public function testHandleDefaultResponse() - { - $this->paymentMock->method('getParentTransactionId') - ->willReturn(null); - // Assert the id is set - $this->paymentMock->expects($this->once()) - ->method('setTransactionId') - ->with('thetransid'); - // Assert the id is set in the additional info for later - $this->paymentMock->expects($this->once()) - ->method('setTransactionAdditionalInfo') - ->with('real_transaction_id', 'thetransid'); - - $response = [ - 'transactionResponse' => [ - 'transId' => 'thetransid', - ] - ]; - $subject = [ - 'payment' => $this->paymentDOMock - ]; - - $this->builder->handle($subject, $response); - // Assertions are part of mocking above - } - - public function testHandleDifferenceInTransactionId() - { - $this->paymentMock->method('getParentTransactionId') - ->willReturn('somethingElse'); - // Assert the id is set - $this->paymentMock->expects($this->once()) - ->method('setTransactionId') - ->with('thetransid'); - - $response = [ - 'transactionResponse' => [ - 'transId' => 'thetransid', - ] - ]; - $subject = [ - 'payment' => $this->paymentDOMock - ]; - - $this->builder->handle($subject, $response); - // Assertions are part of mocking above - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/VoidResponseHandlerTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/VoidResponseHandlerTest.php deleted file mode 100644 index f99da2b2ec90b..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Response/VoidResponseHandlerTest.php +++ /dev/null @@ -1,72 +0,0 @@ -paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $this->paymentMock = $this->createMock(Payment::class); - $this->paymentDOMock->method('getPayment') - ->willReturn($this->paymentMock); - - $this->handler = new VoidResponseHandler(new SubjectReader()); - } - - public function testHandle() - { - $subject = [ - 'payment' => $this->paymentDOMock - ]; - $response = [ - 'transactionResponse' => [ - 'transId' => 'abc123', - ] - ]; - - // Assert the transaction is closed - $this->paymentMock->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(true); - // Assert the parent transaction is closed - $this->paymentMock->expects($this->once()) - ->method('setShouldCloseParentTransaction') - ->with(true); - // Assert the authorize.net transaction id is saved - $this->paymentMock->expects($this->once()) - ->method('setTransactionAdditionalInfo') - ->with('real_transaction_id', 'abc123'); - - $this->handler->handle($subject, $response); - // Assertions are via mock expects above - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/SubjectReaderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/SubjectReaderTest.php deleted file mode 100644 index 42219024badbf..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/SubjectReaderTest.php +++ /dev/null @@ -1,119 +0,0 @@ -subjectReader = new SubjectReader(); - } - - public function testReadPayment(): void - { - $paymentDO = $this->createMock(PaymentDataObjectInterface::class); - - $this->assertSame($paymentDO, $this->subjectReader->readPayment(['payment' => $paymentDO])); - } - - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Payment data object should be provided - */ - public function testReadPaymentThrowsExceptionWhenNotAPaymentObject(): void - { - $this->subjectReader->readPayment(['payment' => 'nope']); - } - - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Payment data object should be provided - */ - public function testReadPaymentThrowsExceptionWhenNotSet(): void - { - $this->subjectReader->readPayment([]); - } - - public function testReadResponse(): void - { - $expected = ['foo' => 'bar']; - - $this->assertSame($expected, $this->subjectReader->readResponse(['response' => $expected])); - } - - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Response does not exist - */ - public function testReadResponseThrowsExceptionWhenNotAvailable(): void - { - $this->subjectReader->readResponse([]); - } - - public function testReadStoreId(): void - { - $this->assertEquals(123, $this->subjectReader->readStoreId(['store_id' => '123'])); - } - - public function testReadStoreIdFromOrder(): void - { - $paymentDOMock = $this->createMock(PaymentDataObjectInterface::class); - $orderMock = $this->createMock(OrderAdapterInterface::class); - $paymentDOMock->method('getOrder') - ->willReturn($orderMock); - $orderMock->method('getStoreID') - ->willReturn('123'); - - $result = $this->subjectReader->readStoreId([ - 'payment' => $paymentDOMock - ]); - - $this->assertEquals(123, $result); - } - - public function testReadLoginId(): void - { - $this->assertEquals('abc', $this->subjectReader->readLoginId([ - 'merchantAuthentication' => ['name' => 'abc'] - ])); - } - - public function testReadTransactionKey(): void - { - $this->assertEquals('abc', $this->subjectReader->readTransactionKey([ - 'merchantAuthentication' => ['transactionKey' => 'abc'] - ])); - } - - public function testReadAmount(): void - { - $this->assertSame('123.12', $this->subjectReader->readAmount(['amount' => 123.12])); - } - - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Amount should be provided - */ - public function testReadAmountThrowsExceptionWhenNotAvailable(): void - { - $this->subjectReader->readAmount([]); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php deleted file mode 100644 index 347cd071acc3a..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php +++ /dev/null @@ -1,161 +0,0 @@ -resultFactoryMock = $this->createMock(ResultInterfaceFactory::class); - $this->validator = new GeneralResponseValidator($this->resultFactoryMock, new SubjectReader()); - } - - public function testValidateParsesSuccess() - { - $args = []; - - $this->resultFactoryMock->method('create') - ->with($this->callback(function ($a) use (&$args) { - // Spy on method call - $args = $a; - - return true; - })) - ->willReturn($this->createMock(ResultInterface::class)); - - $this->validator->validate([ - 'response' => [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'foo', - 'text' => 'bar' - ] - ] - ] - ] - ]); - - $this->assertTrue($args['isValid']); - $this->assertEmpty($args['errorCodes']); - $this->assertEmpty($args['failsDescription']); - } - - public function testValidateParsesErrors() - { - $args = []; - - $this->resultFactoryMock->method('create') - ->with($this->callback(function ($a) use (&$args) { - // Spy on method call - $args = $a; - - return true; - })) - ->willReturn($this->createMock(ResultInterface::class)); - - $this->validator->validate([ - 'response' => [ - 'errors' => [ - 'resultCode' => 'Error', - 'error' => [ - [ - 'errorCode' => 'foo', - 'errorText' => 'bar' - ] - ] - ] - ] - ]); - - $this->assertFalse($args['isValid']); - $this->assertSame(['foo'], $args['errorCodes']); - $this->assertSame(['bar'], $args['failsDescription']); - } - - public function testValidateParsesMessages() - { - $args = []; - - $this->resultFactoryMock->method('create') - ->with($this->callback(function ($a) use (&$args) { - // Spy on method call - $args = $a; - - return true; - })) - ->willReturn($this->createMock(ResultInterface::class)); - - $this->validator->validate([ - 'response' => [ - 'messages' => [ - 'resultCode' => 'Error', - 'message' => [ - [ - 'code' => 'foo', - 'text' => 'bar' - ] - ] - ] - ] - ]); - - $this->assertFalse($args['isValid']); - $this->assertSame(['foo'], $args['errorCodes']); - $this->assertSame(['bar'], $args['failsDescription']); - } - - public function testValidateParsesErrorsWhenOnlyOneIsReturned() - { - $args = []; - - $this->resultFactoryMock->method('create') - ->with($this->callback(function ($a) use (&$args) { - // Spy on method call - $args = $a; - - return true; - })) - ->willReturn($this->createMock(ResultInterface::class)); - - $this->validator->validate([ - 'response' => [ - 'messages' => [ - 'resultCode' => 'Error', - 'message' => [ - 'code' => 'foo', - 'text' => 'bar' - ] - ] - ] - ]); - - $this->assertFalse($args['isValid']); - $this->assertSame(['foo'], $args['errorCodes']); - $this->assertSame(['bar'], $args['failsDescription']); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionHashValidatorTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionHashValidatorTest.php deleted file mode 100644 index fb3f9d0520d49..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionHashValidatorTest.php +++ /dev/null @@ -1,280 +0,0 @@ -resultFactoryMock = $this->createMock(ResultInterfaceFactory::class); - $this->configMock = $this->createMock(Config::class); - $this->resultMock = $this->createMock(ResultInterface::class); - - $this->validator = new TransactionHashValidator( - $this->resultFactoryMock, - new SubjectReader(), - $this->configMock - ); - } - - /** - * @param $response - * @param $isValid - * @param $errorCodes - * @param $errorDescriptions - * @dataProvider sha512ResponseProvider - */ - public function testValidateSha512HashScenarios( - $response, - $isValid, - $errorCodes, - $errorDescriptions - ) { - $args = []; - - $this->resultFactoryMock->method('create') - ->with($this->callback(function ($a) use (&$args) { - // Spy on method call - $args = $a; - - return true; - })) - ->willReturn($this->resultMock); - - $this->configMock->method('getTransactionSignatureKey') - ->willReturn('abc'); - $this->configMock->method('getLoginId') - ->willReturn('username'); - - $this->validator->validate($response); - - $this->assertSame($isValid, $args['isValid']); - $this->assertEquals($errorCodes, $args['errorCodes']); - $this->assertEquals($errorDescriptions, $args['failsDescription']); - } - - /** - * @param $response - * @param $isValid - * @param $errorCodes - * @param $errorDescriptions - * @dataProvider md5ResponseProvider - */ - public function testValidateMd5HashScenarios( - $response, - $isValid, - $errorCodes, - $errorDescriptions - ) { - $args = []; - - $this->resultFactoryMock->method('create') - ->with($this->callback(function ($a) use (&$args) { - // Spy on method call - $args = $a; - - return true; - })) - ->willReturn($this->resultMock); - - $this->configMock->method('getLegacyTransactionHash') - ->willReturn('abc'); - $this->configMock->method('getLoginId') - ->willReturn('username'); - - $this->validator->validate($response); - - $this->assertSame($isValid, $args['isValid']); - $this->assertEquals($errorCodes, $args['errorCodes']); - $this->assertEquals($errorDescriptions, $args['failsDescription']); - } - - public function md5ResponseProvider() - { - return [ - [ - [ - 'response' => [ - 'transactionResponse' => [ - 'transId' => '123', - 'transHash' => 'C8675D9F7BE7BE4A04C18EA1B6F7B6FD' - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'response' => [ - 'transactionResponse' => [ - 'transId' => '123', - 'transHash' => 'C8675D9F7BE7BE4A04C18EA1B6F7B6FD' - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'amount' => '123.00', - 'response' => [ - 'transactionResponse' => [ - 'transHash' => 'bad' - ] - ] - ], - false, - ['ETHV'], - ['The authenticity of the gateway response could not be verified.'] - ], - [ - [ - 'amount' => '123.00', - 'response' => [ - 'transactionResponse' => [ - 'refTransID' => '123', - 'transId' => '123', - 'transHash' => 'C8675D9F7BE7BE4A04C18EA1B6F7B6FD' - ] - ] - ], - true, - [], - [] - ], - ]; - } - - public function sha512ResponseProvider() - { - return [ - [ - [ - 'response' => [ - 'transactionResponse' => [ - 'transId' => '123', - 'refTransID' => '123', - 'transHashSha2' => 'CC0FF465A081D98FFC6E502C40B2DCC7655ACF591F859135B6E66558D' - . '41E3A2C654D5A2ACF4749104F3133711175C232C32676F79F70211C2984B21A33D30DEE' - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'response' => [ - 'transactionResponse' => [ - 'transId' => '0', - 'refTransID' => '123', - 'transHashSha2' => '563D42F4A5189F74334088EF6A02E84F320CD8C005FB0DC436EF96084D' - . 'FAC0C76DE081DFC58A3BF825465C63B7F38E4D463025EAC44597A68C024CBBCE7A3159' - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'amount' => '123.00', - 'response' => [ - 'transactionResponse' => [ - 'transId' => '0', - 'transHashSha2' => 'DEE5309078D9F7A68BA4F706FB3E58618D3991A6A5E4C39DCF9C49E693' - . '673C38BD6BB15C235263C549A6B5F0B6D7019EC729E0C275C9FEA37FB91F8B612D0A5D' - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'amount' => '123.00', - 'response' => [ - 'transactionResponse' => [ - 'transId' => '123', - 'transHashSha2' => '1DBD16DED0DA02F52A22A9AD71A49F70BD2ECD42437552889912DD5CE' - . 'CBA0E09A5E8E6221DA74D98A46E5F77F7774B6D9C39CADF3E9A33D85870A6958DA7C8B2' - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'amount' => '123.00', - 'response' => [ - 'transactionResponse' => [ - 'transId' => '123', - 'refTransID' => '0', - 'transHashSha2' => '1DBD16DED0DA02F52A22A9AD71A49F70BD2ECD42437552889912DD5CE' - . 'CBA0E09A5E8E6221DA74D98A46E5F77F7774B6D9C39CADF3E9A33D85870A6958DA7C8B2' - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'amount' => '123.00', - 'response' => [ - 'transactionResponse' => [ - 'transHashSha2' => 'bad' - ] - ] - ], - false, - ['ETHV'], - ['The authenticity of the gateway response could not be verified.'] - ], - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionResponseValidatorTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionResponseValidatorTest.php deleted file mode 100644 index c59cf00899af2..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Gateway/Validator/TransactionResponseValidatorTest.php +++ /dev/null @@ -1,231 +0,0 @@ -resultFactoryMock = $this->createMock(ResultInterfaceFactory::class); - $this->resultMock = $this->createMock(ResultInterface::class); - - $this->validator = new TransactionResponseValidator( - $this->resultFactoryMock, - new SubjectReader() - ); - } - - /** - * @param $transactionResponse - * @param $isValid - * @param $errorCodes - * @param $errorMessages - * @dataProvider scenarioProvider - */ - public function testValidateScenarios($transactionResponse, $isValid, $errorCodes, $errorMessages) - { - $args = []; - - $this->resultFactoryMock->method('create') - ->with($this->callback(function ($a) use (&$args) { - // Spy on method call - $args = $a; - - return true; - })) - ->willReturn($this->resultMock); - - $this->validator->validate([ - 'response' => [ - 'transactionResponse' => $transactionResponse - ] - ]); - - $this->assertEquals($isValid, $args['isValid']); - $this->assertEquals($errorCodes, $args['errorCodes']); - $this->assertEquals($errorMessages, $args['failsDescription']); - } - - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function scenarioProvider() - { - return [ - // Test for acceptable reason codes - [ - [ - 'responseCode' => self::RESPONSE_CODE_APPROVED, - 'messages' => [ - 'message' => [ - 'code' => self::RESPONSE_REASON_CODE_APPROVED, - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'responseCode' => self::RESPONSE_CODE_APPROVED, - 'messages' => [ - 'message' => [ - 'code' => self::RESPONSE_REASON_CODE_PENDING_REVIEW, - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'responseCode' => self::RESPONSE_CODE_APPROVED, - 'messages' => [ - 'message' => [ - 'code' => self::RESPONSE_REASON_CODE_PENDING_REVIEW_AUTHORIZED, - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'responseCode' => self::RESPONSE_CODE_HELD, - 'messages' => [ - 'message' => [ - 'code' => self::RESPONSE_REASON_CODE_APPROVED, - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'responseCode' => self::RESPONSE_CODE_HELD, - 'messages' => [ - 'message' => [ - 'code' => self::RESPONSE_REASON_CODE_PENDING_REVIEW, - ] - ] - ], - true, - [], - [] - ], - [ - [ - 'responseCode' => self::RESPONSE_CODE_HELD, - 'messages' => [ - 'message' => [ - 'code' => self::RESPONSE_REASON_CODE_PENDING_REVIEW_AUTHORIZED, - ] - ] - ], - true, - [], - [] - ], - - // Test for reason codes that aren't acceptable - [ - [ - 'responseCode' => self::RESPONSE_CODE_APPROVED, - 'messages' => [ - 'message' => [ - [ - 'description' => 'bar', - 'code' => 'foo', - ] - ] - ] - ], - false, - ['foo'], - ['bar'] - ], - [ - [ - 'responseCode' => self::RESPONSE_CODE_APPROVED, - 'messages' => [ - 'message' => [ - // Alternate, non-array sytax - 'text' => 'bar', - 'code' => 'foo', - ] - ] - ], - false, - ['foo'], - ['bar'] - ], - [ - [ - 'responseCode' => self::RESPONSE_CODE_DENIED, - 'errors' => [ - [ - 'errorCode' => self::ERROR_CODE_AVS_MISMATCH, - 'errorText' => 'bar' - ] - ] - ], - false, - [self::ERROR_CODE_AVS_MISMATCH], - ['bar'] - ], - // This validator only cares about successful edge cases so test for default behavior - [ - [ - 'responseCode' => 'foo', - ], - false, - [], - [] - ], - ]; - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Model/Ui/ConfigProviderTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Model/Ui/ConfigProviderTest.php deleted file mode 100644 index dea4557fd584c..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Model/Ui/ConfigProviderTest.php +++ /dev/null @@ -1,76 +0,0 @@ -cart = $this->createMock(CartInterface::class); - $this->config = $this->createMock(Config::class); - $this->provider = new ConfigProvider($this->config, $this->cart); - } - - public function testProviderRetrievesValues() - { - $this->cart->method('getStoreId') - ->willReturn('123'); - - $this->config->method('getClientKey') - ->with('123') - ->willReturn('foo'); - - $this->config->method('getLoginId') - ->with('123') - ->willReturn('bar'); - - $this->config->method('getEnvironment') - ->with('123') - ->willReturn('baz'); - - $this->config->method('isCvvEnabled') - ->with('123') - ->willReturn(false); - - $expected = [ - 'payment' => [ - Config::METHOD => [ - 'clientKey' => 'foo', - 'apiLoginID' => 'bar', - 'environment' => 'baz', - 'useCvv' => false, - ] - ] - ]; - - $this->assertEquals($expected, $this->provider->getConfig()); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Observer/DataAssignObserverTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Observer/DataAssignObserverTest.php deleted file mode 100644 index bd439a336786b..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Observer/DataAssignObserverTest.php +++ /dev/null @@ -1,80 +0,0 @@ - 'foo', - 'opaqueDataValue' => 'bar', - 'ccLast4' => '1234' - ]; - - $observerContainer = $this->createMock(Observer::class); - $event = $this->createMock(Event::class); - $paymentInfoModel = $this->createMock(InfoInterface::class); - $dataObject = new DataObject([PaymentInterface::KEY_ADDITIONAL_DATA => $additionalInfo]); - $observerContainer->method('getEvent') - ->willReturn($event); - $event->method('getDataByKey') - ->willReturnMap( - [ - [AbstractDataAssignObserver::MODEL_CODE, $paymentInfoModel], - [AbstractDataAssignObserver::DATA_CODE, $dataObject] - ] - ); - $paymentInfoModel->expects($this->at(0)) - ->method('setAdditionalInformation') - ->with('opaqueDataDescriptor', 'foo'); - $paymentInfoModel->expects($this->at(1)) - ->method('setAdditionalInformation') - ->with('opaqueDataValue', 'bar'); - $paymentInfoModel->expects($this->at(2)) - ->method('setAdditionalInformation') - ->with('ccLast4', '1234'); - - $observer = new DataAssignObserver(); - $observer->execute($observerContainer); - } - - public function testDoestSetDataWhenEmpty() - { - $observerContainer = $this->createMock(Observer::class); - $event = $this->createMock(Event::class); - $paymentInfoModel = $this->createMock(InfoInterface::class); - $observerContainer->method('getEvent') - ->willReturn($event); - $event->method('getDataByKey') - ->willReturnMap( - [ - [AbstractDataAssignObserver::MODEL_CODE, $paymentInfoModel], - [AbstractDataAssignObserver::DATA_CODE, new DataObject()] - ] - ); - $paymentInfoModel->expects($this->never()) - ->method('setAdditionalInformation'); - - $observer = new DataAssignObserver(); - $observer->execute($observerContainer); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Setup/Patch/Data/CopyCurrentConfigTest.php b/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Setup/Patch/Data/CopyCurrentConfigTest.php deleted file mode 100644 index 5ac8a6ca9b3f6..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/Test/Unit/Setup/Patch/Data/CopyCurrentConfigTest.php +++ /dev/null @@ -1,149 +0,0 @@ -scopeConfig = $this->createMock(Config::class); - $this->resourceConfig = $this->createMock(ResourceConfig::class); - $this->encryptor = $this->createMock(Encryptor::class); - $this->setup = $this->createMock(DataSetup::class); - - $this->setup->expects($this->once()) - ->method('startSetup') - ->willReturn(null); - - $this->setup->expects($this->once()) - ->method('endSetup') - ->willReturn(null); - - $this->context = $this->createMock(ModuleContext::class); - $this->storeManager = $this->createMock(StoreManagerInterface::class); - $this->website = $this->createMock(Website::class); - } - - public function testMigrateData(): void - { - $this->scopeConfig->expects($this->exactly(26)) - ->method('getValue') - ->willReturn('TestValue'); - - $this->resourceConfig->expects($this->exactly(26)) - ->method('saveConfig') - ->willReturn(null); - - $this->encryptor->expects($this->exactly(6)) - ->method('encrypt') - ->willReturn('TestValue'); - - $this->website->expects($this->once()) - ->method('getId') - ->willReturn(1); - - $this->storeManager->expects($this->once()) - ->method('getWebsites') - ->willReturn([$this->website]); - - $objectManager = new ObjectManager($this); - - $installer = $objectManager->getObject( - CopyCurrentConfig::class, - [ - 'moduleDataSetup' => $this->setup, - 'scopeConfig' => $this->scopeConfig, - 'resourceConfig' => $this->resourceConfig, - 'encryptor' => $this->encryptor, - 'storeManager' => $this->storeManager - ] - ); - - $installer->apply($this->context); - } - - public function testMigrateDataNullFields(): void - { - $this->scopeConfig->expects($this->exactly(13)) - ->method('getValue') - ->will($this->onConsecutiveCalls(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); - - $this->resourceConfig->expects($this->exactly(10)) - ->method('saveConfig') - ->willReturn(null); - - $this->encryptor->expects($this->never()) - ->method('encrypt'); - - $this->storeManager->expects($this->once()) - ->method('getWebsites') - ->willReturn([]); - - $objectManager = new ObjectManager($this); - - $installer = $objectManager->getObject( - CopyCurrentConfig::class, - [ - 'moduleDataSetup' => $this->setup, - 'scopeConfig' => $this->scopeConfig, - 'resourceConfig' => $this->resourceConfig, - 'encryptor' => $this->encryptor, - 'storeManager' => $this->storeManager - ] - ); - - $installer->apply($this->context); - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/composer.json b/app/code/Magento/AuthorizenetAcceptjs/composer.json deleted file mode 100644 index a54387ca6de28..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/composer.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "magento/module-authorizenet-acceptjs", - "description": "N/A", - "config": { - "sort-packages": true - }, - "require": { - "php": "~7.1.3||~7.2.0||~7.3.0", - "magento/framework": "*", - "magento/module-payment": "*", - "magento/module-sales": "*", - "magento/module-config": "*", - "magento/module-backend": "*", - "magento/module-checkout": "*", - "magento/module-store": "*", - "magento/module-quote": "*" - }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "autoload": { - "files": [ - "registration.php" - ], - "psr-4": { - "Magento\\AuthorizenetAcceptjs\\": "" - } - } -} diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/di.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/di.xml deleted file mode 100644 index f4059aebbe3e3..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/di.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - Magento\AuthorizenetAcceptjs\Model\Ui\ConfigProvider - - - - - - AuthorizenetAcceptjsTransactionRequestTypeBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StoreConfigBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthenticationDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthorizeDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AmountDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PaymentDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\ShippingDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\SolutionDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\OrderDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PoDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\CustomerDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AddressDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\CustomSettingsBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PassthroughDataBuilder - - - - - - AuthorizenetAcceptjsTransactionValidator - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml deleted file mode 100644 index 86b6d3a198d81..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/adminhtml/system.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - - -
- - - - - Magento\Config\Model\Config\Source\Yesno - - - - - - - 1 - Magento\Config\Block\System\Config\Form\Fieldset - - - payment/authorizenet_acceptjs/title - - - - Magento\AuthorizenetAcceptjs\Model\Adminhtml\Source\Environment - payment/authorizenet_acceptjs/environment - - - - Magento\AuthorizenetAcceptjs\Model\Adminhtml\Source\PaymentAction - payment/authorizenet_acceptjs/payment_action - - - - Magento\Config\Model\Config\Backend\Encrypted - payment/authorizenet_acceptjs/login - required-entry - - 1 - - - - - Magento\Config\Model\Config\Backend\Encrypted - payment/authorizenet_acceptjs/trans_key - required-entry - - 1 - - - - - payment/authorizenet_acceptjs/public_client_key - required-entry - - 1 - - - - - Magento\Config\Model\Config\Backend\Encrypted - payment/authorizenet_acceptjs/trans_signature_key - required-entry - - 1 - - - - - Magento\Config\Model\Config\Backend\Encrypted - payment/authorizenet_acceptjs/trans_md5 - - 1 - - - - - - 0 - - - Magento\Config\Model\Config\Source\Locale\Currency - payment/authorizenet_acceptjs/currency - - - - Magento\Config\Model\Config\Source\Yesno - payment/authorizenet_acceptjs/debug - - - - Magento\Config\Model\Config\Source\Yesno - payment/authorizenet_acceptjs/email_customer - - - - Magento\Config\Model\Config\Source\Yesno - payment/authorizenet_acceptjs/cvv_enabled - - - - Magento\AuthorizenetAcceptjs\Model\Adminhtml\Source\Cctype - payment/authorizenet_acceptjs/cctypes - - - - Magento\Payment\Model\Config\Source\Allspecificcountries - payment/authorizenet_acceptjs/allowspecific - - - - Magento\Directory\Model\Config\Source\Country - payment/authorizenet_acceptjs/specificcountry - - - - payment/authorizenet_acceptjs/min_order_total - validate-number validate-zero-or-greater - - - - payment/authorizenet_acceptjs/max_order_total - validate-number validate-zero-or-greater - - - - validate-number - payment/authorizenet_acceptjs/sort_order - - - -
-
-
diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/authorizenet_acceptjs_error_mapping.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/authorizenet_acceptjs_error_mapping.xml deleted file mode 100644 index 507a9b14f917b..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/authorizenet_acceptjs_error_mapping.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Invalid request to gateway. - Invalid gateway credentials. - Transaction has been declined. Please try again later. - The authenticity of the gateway response could not be verified. - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/config.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/config.xml deleted file mode 100644 index 6fdbb98a78f8b..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/config.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - \.authorize\.net/v1/Accept - - - - - - 0 - AE,VI,MC,DI,JCB,DN - 0 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - AuthorizenetAcceptjsFacade - 0 - - processing - authorize - Credit Card (Authorize.Net) - 1 - - - - - 0 - USD - production - authCode,avsResultCode,cvvResultCode,cavvResultCode - accountType,ccLast4,authCode,avsResultCode,cvvResultCode,cavvResultCode - transactionStatus,responseCode,responseReasonCode,authCode,AVSResponse,cardCodeResponse,CAVVResponse - - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/di.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/di.xml deleted file mode 100644 index 1bff19e15a65f..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/di.xml +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config::METHOD - - - - - authorizenet_acceptjs - Magento\AuthorizenetAcceptjs\Block\Form - AuthorizenetAcceptjsInfoBlock - AuthorizenetAcceptjsValueHandlerPool - AuthorizenetAcceptjsValidatorPool - AuthorizenetAcceptjsCommandPool - - - - - - AuthorizenetAcceptjsAuthorizeCommand - AuthorizenetAcceptjsCaptureCommand - AuthorizenetAcceptjsSaleCommand - AuthorizenetAcceptjsSettleCommand - AuthorizenetAcceptjsVoidCommand - AuthorizenetAcceptjsRefundCommand - AuthorizenetAcceptjsRefundSettledCommand - AuthorizenetAcceptjsCancelCommand - AuthorizenetAcceptjsAcceptPaymentCommand - AuthorizenetAcceptjsAcceptFdsCommand - AuthorizenetAcceptjsCancelCommand - AuthorizenetAcceptjsTransactionDetailsCommand - AuthorizenetAcceptjsFetchTransactionInfoCommand - - - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Validator\GeneralResponseValidator - - - - - - - true - - - Magento\AuthorizenetAcceptjs\Gateway\Validator\GeneralResponseValidator - Magento\AuthorizenetAcceptjs\Gateway\Validator\TransactionResponseValidator - Magento\AuthorizenetAcceptjs\Gateway\Validator\TransactionHashValidator - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Validator\GeneralResponseValidator - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config - - - - - - AuthorizenetAcceptjsCountryValidator - - - - - - - - - AuthorizenetAcceptjsCommandPool - - - - - AuthorizenetAcceptjsTransactionDetailsRequest - AuthorizenetAcceptjsDefaultTransferFactory - Magento\AuthorizenetAcceptjs\Gateway\Http\Client - AuthorizenetAcceptjsTransactionDetailsValidator - - - - - AuthorizenetAcceptjsAuthorizeRequest - AuthorizenetAcceptjsDefaultTransferFactory - Magento\AuthorizenetAcceptjs\Gateway\Http\Client - AuthorizenetAcceptjsAuthorizationHandler - AuthorizenetAcceptjsTransactionValidator - AuthorizenetAcceptjsVirtualErrorMessageMapper - - - - - AuthorizenetAcceptjsAcceptsFdsRequest - AuthorizenetAcceptjsDefaultTransferFactory - Magento\AuthorizenetAcceptjs\Gateway\Http\Client - AuthorizenetAcceptjsAcceptsFdsRequestValidator - - - - - AuthorizenetAcceptjsCommandPool - - - - - AuthorizenetAcceptjsSaleRequest - AuthorizenetAcceptjsSaleHandler - - - - - AuthorizenetAcceptjsCommandPool - - - - - AuthorizenetAcceptjsRefundRequest - AuthorizenetAcceptjsRefundSettledHandler - AuthorizenetAcceptjsTransactionValidator - - - - - AuthorizenetAcceptjsCommandPool - - - - - AuthorizenetAcceptjsCaptureRequest - AuthorizenetAcceptjsCaptureTransactionHandler - AuthorizenetAcceptjsTransactionValidator - - - - - AuthorizenetAcceptjsVoidRequest - AuthorizenetAcceptjsDefaultTransferFactory - Magento\AuthorizenetAcceptjs\Gateway\Http\Client - AuthorizenetAcceptjsVoidHandler - AuthorizenetAcceptjsTransactionValidator - AuthorizenetAcceptjsVirtualErrorMessageMapper - - - - - AuthorizenetAcceptjsCancelHandler - - - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Response\PaymentReviewStatusHandler - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Response\TransactionIdHandler - Magento\AuthorizenetAcceptjs\Gateway\Response\PaymentResponseHandler - Magento\AuthorizenetAcceptjs\Gateway\Response\TransactionDetailsResponseHandler - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Response\CloseParentTransactionHandler - - - - - - false - - - - - - CloseCaptureTransactionHandler - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Response\TransactionIdHandler - Magento\AuthorizenetAcceptjs\Gateway\Response\ClosePartialTransactionHandler - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Response\VoidResponseHandler - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Response\CloseTransactionHandler - Magento\AuthorizenetAcceptjs\Gateway\Response\CloseParentTransactionHandler - - - - - - - - - - - AuthorizenetAcceptjsTransactionDetailsRequestTypeBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StoreConfigBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthenticationDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\TransactionDetailsDataBuilder - - - - - - - AuthorizenetAcceptjsAcceptsFdsRequestTypeBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StoreConfigBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthenticationDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AcceptFdsDataBuilder - - - - - - - AuthorizenetAcceptjsTransactionRequestTypeBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StoreConfigBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthenticationDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthorizeDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AmountDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PaymentDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\ShippingDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\SolutionDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\OrderDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PoDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\CustomerDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AddressDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StubDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\CustomSettingsBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PassthroughDataBuilder - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Request\SaleDataBuilder - - - - - - - AuthorizenetAcceptjsTransactionRequestTypeBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StoreConfigBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthenticationDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\RefundTransactionTypeDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AmountDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\RefundPaymentDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\ShippingDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\RefundReferenceTransactionDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\OrderDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PoDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\CustomerDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AddressDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\CustomSettingsBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PassthroughDataBuilder - - - - - - - AuthorizenetAcceptjsTransactionRequestTypeBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StoreConfigBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthenticationDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\CaptureDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PassthroughDataBuilder - - - - - - - AuthorizenetAcceptjsTransactionRequestTypeBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\StoreConfigBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\AuthenticationDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\VoidDataBuilder - Magento\AuthorizenetAcceptjs\Gateway\Request\PassthroughDataBuilder - - - - - - - - - createTransactionRequest - - - - - getTransactionDetailsRequest - - - - - updateHeldTransactionRequest - - - - - - - - authorizenet_acceptjs_error_mapping.xml - - - - - AuthorizenetAcceptjsErrorMappingConfigReader - authorizenet_acceptjs_error_mapper - - - - - AuthorizenetAcceptjsErrorMappingData - - - - - - - AuthorizenetAcceptjsPaymentReviewStatusHandler - - - - - - AuthorizenetAcceptjsCommandManager - - - - - - - 1 - 1 - 1 - 1 - 1 - 1 - - - 1 - 1 - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config - - - - - - AuthorizenetAcceptjsDefaultValueHandler - - - - - - AuthorizenetAcceptjsCommandPool - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config - - - - - AuthorizenetAcceptjsLogger - - - - - - store_id - - - - - - - AuthorizenetAcceptjsRemoveStoreConfigFilter - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/events.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/events.xml deleted file mode 100644 index 93dc448d1d895..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/events.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/frontend/di.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/frontend/di.xml deleted file mode 100644 index 8b0e570abbd2e..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/frontend/di.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - 1 - - - - - - - Magento\AuthorizenetAcceptjs\Model\Ui\ConfigProvider - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config::METHOD - - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/module.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/module.xml deleted file mode 100644 index 6bc8fe3c4daee..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/module.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml b/app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml deleted file mode 100644 index b9f8d40b03006..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/etc/payment.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - 0 - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/i18n/en_US.csv b/app/code/Magento/AuthorizenetAcceptjs/i18n/en_US.csv deleted file mode 100644 index a8b5dbd2df525..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/i18n/en_US.csv +++ /dev/null @@ -1,22 +0,0 @@ -"Authorize.Net (Deprecated)","Authorize.Net (Deprecated)" -"Gateway URL","Gateway URL" -"Invalid payload type.","Invalid payload type." -"Something went wrong in the payment gateway.","Something went wrong in the payment gateway." -"Merchant MD5 (deprecated","Merchant MD5 (deprecated" -"Signature Key","Signature Key" -"Basic Authorize.Net Settings","Basic Authorize.Net Settings" -"Advanced Authorize.Net Settings","Advanced Authorize.Net Settings" -"Public Client Key","Public Client Key" -"Environment","Environment" -"Production","Production" -"Sandbox","Sandbox" -"accountType","Account Type" -"authCode", "Processor Response Text" -"avsResultCode", "AVS Response Code" -"cvvResultCode","CVV Response Code" -"cavvResultCode","CAVV Response Code" -"Enable Credit Card Verification Field","Enable Credit Card Verification Field" -"ccLast4","Last 4 Digits of Card" -"There was an error while trying to process the refund.","There was an error while trying to process the refund." -"This transaction cannot be refunded with its current status.","This transaction cannot be refunded with its current status." -"The transaction has not been settled, a partial refund is not yet available.","The transaction has not been settled, a partial refund is not yet available." diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/layout/sales_order_create_index.xml b/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/layout/sales_order_create_index.xml deleted file mode 100644 index ee1de3ed7efae..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/layout/sales_order_create_index.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config::METHOD - Magento_AuthorizenetAcceptjs::form/cc.phtml - - - - - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml b/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml deleted file mode 100644 index 13f6d38e2b81a..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - Magento\AuthorizenetAcceptjs\Gateway\Config::METHOD - Magento_AuthorizenetAcceptjs::form/cc.phtml - - - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/templates/form/cc.phtml b/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/templates/form/cc.phtml deleted file mode 100644 index b757e55aaddee..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/templates/form/cc.phtml +++ /dev/null @@ -1,92 +0,0 @@ -escapeHtml($block->getMethodCode()); -$ccType = $block->getInfoData('cc_type'); -$ccExpMonth = $block->getInfoData('cc_exp_month'); -$ccExpYear = $block->getInfoData('cc_exp_year'); -?> - diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/templates/payment/script.phtml b/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/templates/payment/script.phtml deleted file mode 100644 index 6be6008dba507..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/templates/payment/script.phtml +++ /dev/null @@ -1,24 +0,0 @@ - - diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/web/js/authorizenet.js b/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/web/js/authorizenet.js deleted file mode 100644 index 0eb865d7666b3..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/web/js/authorizenet.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'jquery', - 'uiComponent', - 'Magento_Ui/js/modal/alert', - 'Magento_AuthorizenetAcceptjs/js/view/payment/acceptjs-client' -], function ($, Class, alert, AcceptjsClient) { - 'use strict'; - - return Class.extend({ - defaults: { - acceptjsClient: null, - $selector: null, - selector: 'edit_form', - container: 'payment_form_authorizenet_acceptjs', - active: false, - imports: { - onActiveChange: 'active' - } - }, - - /** - * @{inheritdoc} - */ - initConfig: function (config) { - this._super(); - - this.acceptjsClient = AcceptjsClient({ - environment: config.environment - }); - - return this; - }, - - /** - * @{inheritdoc} - */ - initObservable: function () { - this.$selector = $('#' + this.selector); - this._super() - .observe('active'); - - // re-init payment method events - this.$selector.off('changePaymentMethod.' + this.code) - .on('changePaymentMethod.' + this.code, this.changePaymentMethod.bind(this)); - - return this; - }, - - /** - * Enable/disable current payment method - * - * @param {Object} event - * @param {String} method - * @returns {Object} - */ - changePaymentMethod: function (event, method) { - this.active(method === this.code); - - return this; - }, - - /** - * Triggered when payment changed - * - * @param {Boolean} isActive - */ - onActiveChange: function (isActive) { - if (!isActive) { - - return; - } - - this.disableEventListeners(); - - window.order.addExcludedPaymentMethod(this.code); - - this.enableEventListeners(); - }, - - /** - * Sets the payment details on the form - * - * @param {Object} tokens - */ - setPaymentDetails: function (tokens) { - var $ccNumber = $(this.getSelector('cc_number')), - ccLast4 = $ccNumber.val().replace(/[^\d]/g, '').substr(-4); - - $(this.getSelector('opaque_data_descriptor')).val(tokens.opaqueDataDescriptor); - $(this.getSelector('opaque_data_value')).val(tokens.opaqueDataValue); - $(this.getSelector('cc_last_4')).val(ccLast4); - $ccNumber.val(''); - $(this.getSelector('cc_exp_month')).val(''); - $(this.getSelector('cc_exp_year')).val(''); - - if (this.useCvv) { - $(this.getSelector('cc_cid')).val(''); - } - }, - - /** - * Trigger order submit - */ - submitOrder: function () { - var authData = {}, - cardData = {}, - secureData = {}; - - this.$selector.validate().form(); - this.$selector.trigger('afterValidate.beforeSubmit'); - - authData.clientKey = this.clientKey; - authData.apiLoginID = this.apiLoginID; - - cardData.cardNumber = $(this.getSelector('cc_number')).val(); - cardData.month = $(this.getSelector('cc_exp_month')).val(); - cardData.year = $(this.getSelector('cc_exp_year')).val(); - - if (this.useCvv) { - cardData.cardCode = $(this.getSelector('cc_cid')).val(); - } - - secureData.authData = authData; - secureData.cardData = cardData; - - this.disableEventListeners(); - - this.acceptjsClient.createTokens(secureData) - .always(function () { - $('body').trigger('processStop'); - this.enableEventListeners(); - }.bind(this)) - .done(function (tokens) { - this.setPaymentDetails(tokens); - this.placeOrder(); - }.bind(this)) - .fail(function (messages) { - this.tokens = null; - - if (messages.length > 0) { - this._showError(messages[0]); - } - }.bind(this)); - - return false; - }, - - /** - * Place order - */ - placeOrder: function () { - this.$selector.trigger('realOrder'); - }, - - /** - * Get jQuery selector - * - * @param {String} field - * @returns {String} - */ - getSelector: function (field) { - return '#' + this.code + '_' + field; - }, - - /** - * Show alert message - * - * @param {String} message - */ - _showError: function (message) { - alert({ - content: message - }); - }, - - /** - * Enable form event listeners - */ - enableEventListeners: function () { - this.$selector.on('submitOrder.authorizenetacceptjs', this.submitOrder.bind(this)); - }, - - /** - * Disable form event listeners - */ - disableEventListeners: function () { - this.$selector.off('submitOrder'); - this.$selector.off('submit'); - } - - }); -}); diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/web/js/payment-form.js b/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/web/js/payment-form.js deleted file mode 100644 index e3a0886797d63..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/adminhtml/web/js/payment-form.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'Magento_AuthorizenetAcceptjs/js/authorizenet', - 'jquery' -], function (AuthorizenetAcceptjs, $) { - 'use strict'; - - return function (config, element) { - var $form = $(element); - - config.active = $form.length > 0 && !$form.is(':hidden'); - new AuthorizenetAcceptjs(config); - }; -}); diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/base/requirejs-config.js b/app/code/Magento/AuthorizenetAcceptjs/view/base/requirejs-config.js deleted file mode 100644 index 83ddd1094ea1a..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/base/requirejs-config.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -var config = { - shim: { - acceptjs: { - exports: 'Accept' - }, - acceptjssandbox: { - exports: 'Accept' - } - }, - paths: { - acceptjssandbox: 'https://jstest.authorize.net/v1/Accept', - acceptjs: 'https://js.authorize.net/v1/Accept' - } -}; diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-client.js b/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-client.js deleted file mode 100644 index 935465f5298eb..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-client.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery', - 'uiClass', - 'Magento_AuthorizenetAcceptjs/js/view/payment/acceptjs-factory', - 'Magento_AuthorizenetAcceptjs/js/view/payment/validator-handler' -], function ($, Class, acceptjsFactory, validatorHandler) { - 'use strict'; - - return Class.extend({ - defaults: { - environment: 'production' - }, - - /** - * @{inheritdoc} - */ - initialize: function () { - validatorHandler.initialize(); - - this._super(); - - return this; - }, - - /** - * Creates the token pair with the provided data - * - * @param {Object} data - * @return {jQuery.Deferred} - */ - createTokens: function (data) { - var deferred = $.Deferred(); - - if (this.acceptjsClient) { - this._createTokens(deferred, data); - } else { - acceptjsFactory(this.environment) - .done(function (client) { - this.acceptjsClient = client; - this._createTokens(deferred, data); - }.bind(this)); - } - - return deferred.promise(); - }, - - /** - * Creates a token from the payment information in the form - * - * @param {jQuery.Deferred} deferred - * @param {Object} data - */ - _createTokens: function (deferred, data) { - this.acceptjsClient.dispatchData(data, function (response) { - validatorHandler.validate(response, function (valid, messages) { - if (valid) { - deferred.resolve({ - opaqueDataDescriptor: response.opaqueData.dataDescriptor, - opaqueDataValue: response.opaqueData.dataValue - }); - } else { - deferred.reject(messages); - } - }); - }); - } - }); -}); diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-factory.js b/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-factory.js deleted file mode 100644 index e98a204e36cee..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/acceptjs-factory.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery' -], function ($) { - 'use strict'; - - return function (environment) { - var deferred = $.Deferred(), - dependency = 'acceptjs'; - - if (environment === 'sandbox') { - dependency = 'acceptjssandbox'; - } - - require([dependency], function (accept) { - var $body = $('body'); - - /* - * Acceptjs doesn't safely load dependent files which leads to a race condition when trying to use - * the sdk right away. - * @see https://community.developer.authorize.net/t5/Integration-and-Testing/ - * Dynamically-loading-Accept-js-E-WC-03-Accept-js-is-not-loaded/td-p/63283 - */ - $body.on('handshake.acceptjs', function () { - deferred.resolve(accept); - $body.off('handshake.acceptjs'); - }); - }, - deferred.reject - ); - - return deferred.promise(); - }; -}); diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/response-validator.js b/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/response-validator.js deleted file mode 100644 index 3c44ca2f9e490..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/response-validator.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery', - 'mage/translate' -], function ($, $t) { - 'use strict'; - - return { - /** - * Validate Authorizenet-Acceptjs response - * - * @param {Object} context - * @returns {jQuery.Deferred} - */ - validate: function (context) { - var state = $.Deferred(), - messages = []; - - if (context.messages.resultCode === 'Ok') { - state.resolve(); - } else { - if (context.messages.message.length > 0) { - $.each(context.messages.message, function (index, element) { - messages.push($t(element.text)); - }); - } - state.reject(messages); - } - - return state.promise(); - } - }; -}); - diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/validator-handler.js b/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/validator-handler.js deleted file mode 100644 index 109f159c9a77c..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/base/web/js/view/payment/validator-handler.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery', - 'Magento_AuthorizenetAcceptjs/js/view/payment/response-validator' -], function ($, responseValidator) { - 'use strict'; - - return { - validators: [], - - /** - * Init list of validators - */ - initialize: function () { - this.add(responseValidator); - }, - - /** - * Add new validator - * @param {Object} validator - */ - add: function (validator) { - this.validators.push(validator); - }, - - /** - * Run pull of validators - * @param {Object} context - * @param {Function} callback - */ - validate: function (context, callback) { - var self = this, - deferred; - - // no available validators - if (!self.validators.length) { - callback(true); - - return; - } - - // get list of deferred validators - deferred = $.map(self.validators, function (current) { - return current.validate(context); - }); - - $.when.apply($, deferred) - .done(function () { - callback(true); - }).fail(function (error) { - callback(false, error); - }); - } - }; -}); diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/layout/checkout_index_index.xml b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/layout/checkout_index_index.xml deleted file mode 100644 index f31b06c9be9b9..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/layout/checkout_index_index.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - uiComponent - - - - - - - - Magento_AuthorizenetAcceptjs/js/view/payment/authorizenet - - - true - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/authorizenet.js b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/authorizenet.js deleted file mode 100644 index a05fe739a444a..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/authorizenet.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'uiComponent', - 'Magento_Checkout/js/model/payment/renderer-list' -], -function (Component, rendererList) { - 'use strict'; - - rendererList.push({ - type: 'authorizenet_acceptjs', - component: 'Magento_AuthorizenetAcceptjs/js/view/payment/method-renderer/authorizenet-accept' - }); - - /** Add view logic here if needed */ - return Component.extend({}); -}); diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js deleted file mode 100644 index bba1290a9eedd..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/js/view/payment/method-renderer/authorizenet-accept.js +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'jquery', - 'Magento_Payment/js/view/payment/cc-form', - 'Magento_AuthorizenetAcceptjs/js/view/payment/acceptjs-client', - 'Magento_Checkout/js/model/full-screen-loader', - 'Magento_Ui/js/model/messageList', - 'Magento_Payment/js/model/credit-card-validation/validator' -], function ($, Component, AcceptjsClient, fullScreenLoader, globalMessageList) { - 'use strict'; - - return Component.extend({ - defaults: { - active: false, - template: 'Magento_AuthorizenetAcceptjs/payment/authorizenet-acceptjs', - tokens: null, - ccForm: 'Magento_Payment/payment/cc-form', - acceptjsClient: null - }, - - /** - * Set list of observable attributes - * - * @returns {exports.initObservable} - */ - initObservable: function () { - this._super() - .observe(['active']); - - return this; - }, - - /** - * @returns {String} - */ - getCode: function () { - return 'authorizenet_acceptjs'; - }, - - /** - * Initialize form elements for validation - */ - initFormElement: function (element) { - this.formElement = element; - this.acceptjsClient = AcceptjsClient({ - environment: window.checkoutConfig.payment[this.getCode()].environment - }); - $(this.formElement).validation(); - }, - - /** - * @returns {Object} - */ - getData: function () { - return { - method: this.getCode(), - 'additional_data': { - opaqueDataDescriptor: this.tokens ? this.tokens.opaqueDataDescriptor : null, - opaqueDataValue: this.tokens ? this.tokens.opaqueDataValue : null, - ccLast4: this.creditCardNumber().substr(-4) - } - }; - }, - - /** - * Check if payment is active - * - * @returns {Boolean} - */ - isActive: function () { - var active = this.getCode() === this.isChecked(); - - this.active(active); - - return active; - }, - - /** - * Prepare data to place order - */ - beforePlaceOrder: function () { - var authData = {}, - cardData = {}, - secureData = {}; - - if (!$(this.formElement).valid()) { - return; - } - - authData.clientKey = window.checkoutConfig.payment[this.getCode()].clientKey !== null ? - window.checkoutConfig.payment[this.getCode()].clientKey : ''; - authData.apiLoginID = window.checkoutConfig.payment[this.getCode()].apiLoginID !== null ? - window.checkoutConfig.payment[this.getCode()].apiLoginID : ''; - - cardData.cardNumber = this.creditCardNumber(); - cardData.month = this.creditCardExpMonth(); - cardData.year = this.creditCardExpYear(); - - if (this.hasVerification()) { - cardData.cardCode = this.creditCardVerificationNumber(); - } - - secureData.authData = authData; - secureData.cardData = cardData; - - fullScreenLoader.startLoader(); - - this.acceptjsClient.createTokens(secureData) - .always(function () { - fullScreenLoader.stopLoader(); - }) - .done(function (tokens) { - this.tokens = tokens; - this.placeOrder(); - }.bind(this)) - .fail(function (messages) { - this.tokens = null; - this._showErrors(messages); - }.bind(this)); - }, - - /** - * Should the cvv field be used - * - * @return {Boolean} - */ - hasVerification: function () { - return window.checkoutConfig.payment[this.getCode()].useCvv; - }, - - /** - * Show error messages - * - * @param {String[]} errorMessages - */ - _showErrors: function (errorMessages) { - $.each(errorMessages, function (index, message) { - globalMessageList.addErrorMessage({ - message: message - }); - }); - } - }); -}); diff --git a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/template/payment/authorizenet-acceptjs.html b/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/template/payment/authorizenet-acceptjs.html deleted file mode 100644 index 1e41c2b49adba..0000000000000 --- a/app/code/Magento/AuthorizenetAcceptjs/view/frontend/web/template/payment/authorizenet-acceptjs.html +++ /dev/null @@ -1,46 +0,0 @@ - -
-
- - -
-
- -
- -
-
- - -
- -
-
-
- -
-
-
-
diff --git a/app/code/Magento/AuthorizenetCardinal/Gateway/Request/Authorize3DSecureBuilder.php b/app/code/Magento/AuthorizenetCardinal/Gateway/Request/Authorize3DSecureBuilder.php deleted file mode 100644 index bf8e1661a3f61..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/Gateway/Request/Authorize3DSecureBuilder.php +++ /dev/null @@ -1,85 +0,0 @@ -subjectReader = $subjectReader; - $this->config = $config; - $this->jwtParser = $jwtParser; - } - - /** - * @inheritdoc - */ - public function build(array $buildSubject): array - { - if ($this->config->isActive() === false) { - return []; - } - - $paymentDO = $this->subjectReader->readPayment($buildSubject); - $payment = $paymentDO->getPayment(); - $data = []; - - if ($payment instanceof Payment) { - $cardinalJwt = (string)$payment->getAdditionalInformation('cardinalJWT'); - $jwtPayload = $this->jwtParser->execute($cardinalJwt); - $eciFlag = $jwtPayload['Payload']['Payment']['ExtendedData']['ECIFlag'] ?? ''; - $cavv = $jwtPayload['Payload']['Payment']['ExtendedData']['CAVV'] ?? ''; - $data = [ - 'transactionRequest' => [ - 'cardholderAuthentication' => [ - 'authenticationIndicator' => $eciFlag, - 'cardholderAuthenticationValue' => $cavv - ], - ] - ]; - } - - return $data; - } -} diff --git a/app/code/Magento/AuthorizenetCardinal/Gateway/Validator/CavvResponseValidator.php b/app/code/Magento/AuthorizenetCardinal/Gateway/Validator/CavvResponseValidator.php deleted file mode 100644 index 35287406a12d5..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/Gateway/Validator/CavvResponseValidator.php +++ /dev/null @@ -1,86 +0,0 @@ -resultFactory = $resultFactory; - $this->subjectReader = $subjectReader; - $this->config = $config; - } - - /** - * @inheritdoc - */ - public function validate(array $validationSubject): ResultInterface - { - if ($this->config->isActive() === false) { - return $this->createResult(true); - } - - $response = $this->subjectReader->readResponse($validationSubject); - $transactionResponse = $response['transactionResponse']; - - $cavvResultCode = $transactionResponse['cavvResultCode'] ?? ''; - $isValid = $cavvResultCode === self::RESULT_CODE_SUCCESS; - $errorCodes = []; - $errorMessages = []; - - if (!$isValid) { - $errorCodes[] = $transactionResponse['cavvResultCode']; - $errorMessages[] = 'CAVV failed validation'; - } - - return $this->createResult($isValid, $errorMessages, $errorCodes); - } -} diff --git a/app/code/Magento/AuthorizenetCardinal/Model/Checkout/ConfigProvider.php b/app/code/Magento/AuthorizenetCardinal/Model/Checkout/ConfigProvider.php deleted file mode 100644 index 8f09395874dce..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/Model/Checkout/ConfigProvider.php +++ /dev/null @@ -1,48 +0,0 @@ -config = $config; - } - - /** - * @inheritdoc - */ - public function getConfig(): array - { - $config['cardinal'] = [ - 'isActiveFor' => [ - 'authorizenet' => $this->config->isActive() - ] - ]; - - return $config; - } -} diff --git a/app/code/Magento/AuthorizenetCardinal/Model/Config.php b/app/code/Magento/AuthorizenetCardinal/Model/Config.php deleted file mode 100644 index 798fb846c160e..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/Model/Config.php +++ /dev/null @@ -1,52 +0,0 @@ -scopeConfig = $scopeConfig; - } - - /** - * If this config option set to false no AuthorizenetCardinal integration should be available - * - * @param int|null $storeId - * @return bool - */ - public function isActive(?int $storeId = null): bool - { - $enabled = $this->scopeConfig->isSetFlag( - 'three_d_secure/cardinal/enabled_authorizenet', - ScopeInterface::SCOPE_STORE, - $storeId - ); - - return $enabled; - } -} diff --git a/app/code/Magento/AuthorizenetCardinal/Observer/DataAssignObserver.php b/app/code/Magento/AuthorizenetCardinal/Observer/DataAssignObserver.php deleted file mode 100644 index aa5fbee327fe5..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/Observer/DataAssignObserver.php +++ /dev/null @@ -1,66 +0,0 @@ -config = $config; - } - - /** - * @inheritdoc - */ - public function execute(Observer $observer) - { - if ($this->config->isActive() === false) { - return; - } - - $data = $this->readDataArgument($observer); - $additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA); - if (!is_array($additionalData)) { - return; - } - - $paymentInfo = $this->readPaymentModelArgument($observer); - if (isset($additionalData[self::JWT_KEY])) { - $paymentInfo->setAdditionalInformation( - self::JWT_KEY, - $additionalData[self::JWT_KEY] - ); - } - } -} diff --git a/app/code/Magento/AuthorizenetCardinal/README.md b/app/code/Magento/AuthorizenetCardinal/README.md deleted file mode 100644 index 0bd63130471bd..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Magento_AuthorizenetCardinal module - -Use the Magento_AuthorizenetCardinal module to enable 3D Secure 2.0 support for AuthorizenetAcceptjs payment integrations. - -## Structure - -`Gateway/` - the directory that contains payment gateway command interfaces and service classes. - -For information about typical file structure of a module in Magento 2, see [Module file structure](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/build/module-file-structure.html#module-file-structure). - -## Extensibility - -Extension developers can interact with the Magento_AuthorizenetCardinal module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). - -[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_AuthorizenetCardinal module. - -### Events - -This module observes the following events: - -- `payment_method_assign_data_authorizenet_acceptjs` event in the `Magento\AuthorizenetCardinal\Observer\DataAssignObserver` file. - -For information about an event in Magento 2, see [Events and observers](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/events-and-observers.html#events). diff --git a/app/code/Magento/AuthorizenetCardinal/Test/Unit/Observer/DataAssignObserverTest.php b/app/code/Magento/AuthorizenetCardinal/Test/Unit/Observer/DataAssignObserverTest.php deleted file mode 100644 index 9f560507e34db..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/Test/Unit/Observer/DataAssignObserverTest.php +++ /dev/null @@ -1,100 +0,0 @@ - 'foo' - ]; - - $config = $this->createMock(Config::class); - $config->method('isActive') - ->willReturn(true); - $observerContainer = $this->createMock(Observer::class); - $event = $this->createMock(Event::class); - $paymentInfoModel = $this->createMock(InfoInterface::class); - $dataObject = new DataObject([PaymentInterface::KEY_ADDITIONAL_DATA => $additionalInfo]); - $observerContainer->method('getEvent') - ->willReturn($event); - $event->method('getDataByKey') - ->willReturnMap( - [ - [AbstractDataAssignObserver::MODEL_CODE, $paymentInfoModel], - [AbstractDataAssignObserver::DATA_CODE, $dataObject] - ] - ); - $paymentInfoModel->expects($this->once()) - ->method('setAdditionalInformation') - ->with('cardinalJWT', 'foo'); - - $observer = new DataAssignObserver($config); - $observer->execute($observerContainer); - } - - /** - * Tests case when Cardinal JWT is absent. - */ - public function testDoesntSetDataWhenEmpty() - { - $config = $this->createMock(Config::class); - $config->method('isActive') - ->willReturn(true); - $observerContainer = $this->createMock(Observer::class); - $event = $this->createMock(Event::class); - $paymentInfoModel = $this->createMock(InfoInterface::class); - $observerContainer->method('getEvent') - ->willReturn($event); - $event->method('getDataByKey') - ->willReturnMap( - [ - [AbstractDataAssignObserver::MODEL_CODE, $paymentInfoModel], - [AbstractDataAssignObserver::DATA_CODE, new DataObject()] - ] - ); - $paymentInfoModel->expects($this->never()) - ->method('setAdditionalInformation'); - - $observer = new DataAssignObserver($config); - $observer->execute($observerContainer); - } - - /** - * Tests case when CardinalCommerce is disabled. - */ - public function testDoesntSetDataWhenDisabled() - { - $config = $this->createMock(Config::class); - $config->method('isActive') - ->willReturn(false); - $observerContainer = $this->createMock(Observer::class); - $observerContainer->expects($this->never()) - ->method('getEvent'); - $observer = new DataAssignObserver($config); - $observer->execute($observerContainer); - } -} diff --git a/app/code/Magento/AuthorizenetCardinal/composer.json b/app/code/Magento/AuthorizenetCardinal/composer.json deleted file mode 100644 index 8b913f7056033..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/composer.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "magento/module-authorizenet-cardinal", - "description": "Provides a possibility to enable 3-D Secure 2.0 support for Authorize.Net Acceptjs.", - "config": { - "sort-packages": true - }, - "require": { - "php": "~7.1.3||~7.2.0||~7.3.0", - "magento/module-authorizenet-acceptjs": "*", - "magento/framework": "*", - "magento/module-cardinal-commerce": "*", - "magento/module-payment": "*", - "magento/module-sales": "*", - "magento/module-quote": "*", - "magento/module-checkout": "*", - "magento/module-store": "*" - }, - "type": "magento2-module", - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "autoload": { - "files": [ - "registration.php" - ], - "psr-4": { - "Magento\\AuthorizenetCardinal\\": "" - } - } -} diff --git a/app/code/Magento/AuthorizenetCardinal/etc/adminhtml/system.xml b/app/code/Magento/AuthorizenetCardinal/etc/adminhtml/system.xml deleted file mode 100644 index cf8ad28d26d0e..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/etc/adminhtml/system.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
- - - - - Magento\Config\Model\Config\Source\Yesno - three_d_secure/cardinal/enabled_authorizenet - - - -
-
-
diff --git a/app/code/Magento/AuthorizenetCardinal/etc/config.xml b/app/code/Magento/AuthorizenetCardinal/etc/config.xml deleted file mode 100644 index d94bcdc479008..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/etc/config.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - 0 - - - - diff --git a/app/code/Magento/AuthorizenetCardinal/etc/di.xml b/app/code/Magento/AuthorizenetCardinal/etc/di.xml deleted file mode 100644 index 568cb6f4cfc4c..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/etc/di.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - Magento\AuthorizenetCardinal\Gateway\Request\Authorize3DSecureBuilder - - - - - - - true - - - AuthorizenetAcceptjsTransactionValidator - Magento\AuthorizenetCardinal\Gateway\Validator\CavvResponseValidator - - - - - - Magento\AuthorizenetCardinal\Gateway\Validator\VirtualTransactionValidator - - - diff --git a/app/code/Magento/AuthorizenetCardinal/etc/events.xml b/app/code/Magento/AuthorizenetCardinal/etc/events.xml deleted file mode 100644 index 5b0afbe684699..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/etc/events.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - diff --git a/app/code/Magento/AuthorizenetCardinal/etc/frontend/di.xml b/app/code/Magento/AuthorizenetCardinal/etc/frontend/di.xml deleted file mode 100644 index 13c7a223e82d9..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/etc/frontend/di.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - Magento\AuthorizenetCardinal\Model\Checkout\ConfigProvider - - - - - diff --git a/app/code/Magento/AuthorizenetCardinal/view/frontend/requirejs-config.js b/app/code/Magento/AuthorizenetCardinal/view/frontend/requirejs-config.js deleted file mode 100644 index 81823cb2afc58..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/view/frontend/requirejs-config.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -var config = { - config: { - mixins: { - 'Magento_AuthorizenetAcceptjs/js/view/payment/method-renderer/authorizenet-accept': { - 'Magento_AuthorizenetCardinal/js/authorizenet-accept-mixin': true - } - } - } -}; - diff --git a/app/code/Magento/AuthorizenetCardinal/view/frontend/web/js/authorizenet-accept-mixin.js b/app/code/Magento/AuthorizenetCardinal/view/frontend/web/js/authorizenet-accept-mixin.js deleted file mode 100644 index 20a917fc0f050..0000000000000 --- a/app/code/Magento/AuthorizenetCardinal/view/frontend/web/js/authorizenet-accept-mixin.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'jquery', - 'Magento_CardinalCommerce/js/cardinal-client', - 'Magento_Checkout/js/model/full-screen-loader', - 'Magento_Ui/js/model/messageList' -], function ($, cardinalClient, fullScreenLoader, globalMessageList) { - 'use strict'; - - return function (originalComponent) { - return originalComponent.extend({ - defaults: { - cardinalJWT: null - }, - - /** - * Performs 3d-secure authentication - */ - beforePlaceOrder: function () { - var original = this._super.bind(this), - client = cardinalClient, - isActive = window.checkoutConfig.cardinal.isActiveFor.authorizenet, - cardData; - - if (!isActive || !$(this.formElement).valid()) { - return original(); - } - - cardData = { - accountNumber: this.creditCardNumber(), - expMonth: this.creditCardExpMonth(), - expYear: this.creditCardExpYear() - }; - - if (this.hasVerification()) { - cardData.cardCode = this.creditCardVerificationNumber(); - } - - fullScreenLoader.startLoader(); - client.startAuthentication(cardData) - .always(function () { - fullScreenLoader.stopLoader(); - }) - .done(function (jwt) { - this.cardinalJWT = jwt; - original(); - }.bind(this)) - .fail(function (errorMessage) { - globalMessageList.addErrorMessage({ - message: errorMessage - }); - }); - }, - - /** - * Adds cardinal response JWT to payment additional data. - * - * @returns {Object} - */ - getData: function () { - var originalData = this._super(); - - originalData['additional_data'].cardinalJWT = this.cardinalJWT; - - return originalData; - } - }); - }; -}); diff --git a/app/code/Magento/AuthorizenetGraphQl/Model/AuthorizenetDataProvider.php b/app/code/Magento/AuthorizenetGraphQl/Model/AuthorizenetDataProvider.php deleted file mode 100644 index 27d0693884121..0000000000000 --- a/app/code/Magento/AuthorizenetGraphQl/Model/AuthorizenetDataProvider.php +++ /dev/null @@ -1,71 +0,0 @@ -arrayManager = $arrayManager; - } - - /** - * Return additional data - * - * @param array $data - * @return array - * @throws GraphQlInputException - */ - public function getData(array $data): array - { - if (!isset($data[self::PATH_ADDITIONAL_DATA])) { - throw new GraphQlInputException( - __('Required parameter "authorizenet_acceptjs" for "payment_method" is missing.') - ); - } - - $additionalData = $this->arrayManager->get(static::PATH_ADDITIONAL_DATA, $data); - foreach ($additionalData as $key => $value) { - $additionalData[$this->convertSnakeCaseToCamelCase($key)] = $value; - unset($additionalData[$key]); - } - return $additionalData; - } - - /** - * Convert an input string from snake_case to camelCase. - * - * @param string $input - * @return string - */ - private function convertSnakeCaseToCamelCase($input): string - { - return lcfirst(str_replace('_', '', ucwords($input, '_'))); - } -} diff --git a/app/code/Magento/AuthorizenetGraphQl/README.md b/app/code/Magento/AuthorizenetGraphQl/README.md deleted file mode 100644 index 2af2b6a1024af..0000000000000 --- a/app/code/Magento/AuthorizenetGraphQl/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Magento_AuthorizenetGraphQl module - -The Magento_AuthorizenetGraphQl module defines the data types needed to pass payment information data from the client to Magento. - -## Extensibility - -Extension developers can interact with the Magento_AuthorizenetGraphQl module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). - -[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_AuthorizenetGraphQl module. diff --git a/app/code/Magento/AuthorizenetGraphQl/etc/graphql/di.xml b/app/code/Magento/AuthorizenetGraphQl/etc/graphql/di.xml deleted file mode 100644 index e8ea45091c044..0000000000000 --- a/app/code/Magento/AuthorizenetGraphQl/etc/graphql/di.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - Magento\AuthorizenetGraphQl\Model\AuthorizenetDataProvider - - - - diff --git a/app/code/Magento/AuthorizenetGraphQl/etc/schema.graphqls b/app/code/Magento/AuthorizenetGraphQl/etc/schema.graphqls deleted file mode 100644 index b6e817cc91d61..0000000000000 --- a/app/code/Magento/AuthorizenetGraphQl/etc/schema.graphqls +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright © Magento, Inc. All rights reserved. -# See COPYING.txt for license details. - -input PaymentMethodInput { - authorizenet_acceptjs: AuthorizenetInput @doc(description: "Defines the required attributes for Authorize.Net payments") -} - -input AuthorizenetInput { - opaque_data_descriptor: String! @doc(description: "Authorize.Net's description of the transaction request") - opaque_data_value: String! @doc(description: "The nonce returned by Authorize.Net") - cc_last_4: Int! @doc(description: "The last four digits of the credit or debit card") -} \ No newline at end of file diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminSuccessLoginActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminSuccessLoginActionGroup.xml index 1f0ce1824fead..f669c4b9f3ca4 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminSuccessLoginActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/AssertAdminSuccessLoginActionGroup.xml @@ -14,5 +14,6 @@ + diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginActionGroup.xml deleted file mode 100644 index 4afabe2d0eff3..0000000000000 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginActionGroup.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAdminWithCredentialsActionGroup.xml deleted file mode 100644 index cc124990c92ca..0000000000000 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - Login to Backend Admin using provided Admin credentials. PLEASE NOTE: This Action Group does NOT validate that you are Logged In. - - - - - - - - - - - - - diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAdminActionGroup.xml deleted file mode 100644 index 6fe9f184f5ecf..0000000000000 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAdminActionGroup.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Login to Backend Admin using provided User Data. PLEASE NOTE: This Action Group does NOT validate that you are Logged In. - - - - - - - - - - - - diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAnyUserActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAnyUserActionGroup.xml deleted file mode 100644 index b6cec9056bd5d..0000000000000 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LoginAsAnyUserActionGroup.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LogoutActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LogoutActionGroup.xml deleted file mode 100644 index ec79c982e730c..0000000000000 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/LogoutActionGroup.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/app/code/Magento/Backend/Test/Mftf/Section/AdminMessagesSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/AdminMessagesSection.xml index bb1123d01c867..7983554051f89 100644 --- a/app/code/Magento/Backend/Test/Mftf/Section/AdminMessagesSection.xml +++ b/app/code/Magento/Backend/Test/Mftf/Section/AdminMessagesSection.xml @@ -9,6 +9,8 @@
+ + @@ -16,8 +18,7 @@ - - + diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml index 0a54b3f66153a..972947656cd3d 100644 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml +++ b/app/code/Magento/Backend/Test/Mftf/Test/AdminDashboardWithChartsChart.xml @@ -28,6 +28,7 @@ John1 Doe1 + @@ -82,8 +83,8 @@ - - + + @@ -94,8 +95,7 @@ - - + diff --git a/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginTest.xml b/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginTest.xml deleted file mode 100644 index 09893f5f51e5e..0000000000000 --- a/app/code/Magento/Backend/Test/Mftf/Test/AdminLoginTest.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - <description value="Admin should be able to log into the Magento Admin backend"/> - <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-71572"/> - <group value="example"/> - <group value="login"/> - </annotations> - - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <seeInCurrentUrl url="{{AdminLoginPage.url}}" stepKey="seeAdminLoginUrl"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> - </test> -</tests> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml index 0747e785c4ae4..f06e63a2a29c1 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/BraintreeCreditCardOnCheckoutTest.xml @@ -30,6 +30,7 @@ <createData entity="Simple_US_Customer" stepKey="customer"/> <createData entity="BraintreeConfig" stepKey="BraintreeConfigurationData"/> <createData entity="CustomBraintreeConfigurationData" stepKey="CustomBraintreeConfigurationData"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> @@ -43,10 +44,15 @@ <!--Go to storefront--> <amOnPage url="" stepKey="DoToStorefront"/> <!--Create account--> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUserFromStorefrontActionGroup"> - <argument name="Customer" value="Simple_US_Customer"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Simple_US_Customer"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> - <!--Add product to cart--> <amOnPage url="$$product.sku$$.html" stepKey="goToProductPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest.xml index 9334b3beaa4c1..3052bba3c5ae9 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CreateAnAdminOrderUsingBraintreePaymentTest.xml @@ -33,6 +33,7 @@ <!--Create New Customer--> <createData stepKey="createCustomer" entity="Simple_US_Customer"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> diff --git a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscountTest.xml b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscountTest.xml index 743eed209ebf4..9a843370f2c8e 100644 --- a/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscountTest.xml +++ b/app/code/Magento/Braintree/Test/Mftf/Test/CretateAdminOrderWithOnlinePaymentIncludingTaxAndDiscountTest.xml @@ -43,6 +43,8 @@ <field key="group_id">3</field> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> + <!--Login as Admin User--> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> diff --git a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductActionGroup.xml b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductActionGroup.xml index 7e17822710a18..952ae69d887d4 100644 --- a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductActionGroup.xml +++ b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductActionGroup.xml @@ -61,5 +61,7 @@ <requiredEntity createDataKey="createBundleOption1_2"/> <requiredEntity createDataKey="simpleProduct4"/> </createData> + + <magentoCron stepKey="runCronIndex" groups="index"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductAllOptionTypesActionGroup.xml b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductAllOptionTypesActionGroup.xml index c9f5c52c05736..84b0dc1449878 100644 --- a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductAllOptionTypesActionGroup.xml +++ b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiDynamicBundleProductAllOptionTypesActionGroup.xml @@ -70,5 +70,6 @@ <requiredEntity createDataKey="createBundleRadioButtonsOption"/> <requiredEntity createDataKey="simpleProduct2"/> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiFixedBundleProductActionGroup.xml b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiFixedBundleProductActionGroup.xml index 13c31cf2e7127..bfeb5c6bcb4b9 100644 --- a/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiFixedBundleProductActionGroup.xml +++ b/app/code/Magento/Bundle/Test/Mftf/ActionGroup/AdminCreateApiFixedBundleProductActionGroup.xml @@ -61,5 +61,6 @@ <requiredEntity createDataKey="createBundleOption1_2"/> <requiredEntity createDataKey="simpleProduct4"/> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml index 0871a6723417f..4a78aeb752ca7 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleItemsTest.xml @@ -25,6 +25,7 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> <createData entity="SimpleProduct2" stepKey="simpleProduct3"/> + <magentoCron stepKey="runCronIndex" groups="index"/> <!--Admin login--> <actionGroup stepKey="loginToAdminPanel" ref="AdminLoginActionGroup"/> </before> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleProductToCartFromWishListPageTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleProductToCartFromWishListPageTest.xml index 803beb30d677b..9722835b201c1 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleProductToCartFromWishListPageTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddBundleProductToCartFromWishListPageTest.xml @@ -50,6 +50,8 @@ <requiredEntity createDataKey="bundleOption"/> <requiredEntity createDataKey="createSimpleProduct2"/> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToProductEditPage"> <argument name="productId" value="$$createProduct.id$$"/> </actionGroup> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml index 73ced5eaf1592..55038b0c68c44 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml @@ -22,6 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultVideoBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultVideoBundleProductTest.xml index 2f2326b465062..3caa2c9681f55 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultVideoBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultVideoBundleProductTest.xml @@ -24,6 +24,7 @@ <before> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml index 8dad41ca780af..51c30ef86242c 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml @@ -22,6 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml index 3ce398f9c33ba..5b603ef2f0a44 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleDynamicProductTest.xml @@ -26,6 +26,7 @@ <createData entity="ApiBundleProductPriceViewRange" stepKey="createDynamicBundleProduct"> <requiredEntity createDataKey="createCategory"/> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleFixedProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleFixedProductTest.xml index 1f37468ea245c..46244603f2868 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleFixedProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteBundleFixedProductTest.xml @@ -23,6 +23,7 @@ <createData entity="FixedBundleProduct" stepKey="createFixedBundleProduct"> <requiredEntity createDataKey="createCategory"/> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml index 2fe5981eb36c7..4ba5d0f66e096 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml @@ -23,6 +23,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleProduct2" stepKey="simpleProduct0"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!-- Delete the bundled product --> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml index f34ebd4b93cdc..f8914656cc32b 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml @@ -22,6 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProducts.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProducts.xml index 81bd46fdb5412..2c1fcb6d7de42 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProducts.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProducts.xml @@ -24,6 +24,7 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> <createData entity="SimpleProduct2" stepKey="simpleProduct3"/> <createData entity="SimpleProduct2" stepKey="simpleProduct4"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!--Clear Filters--> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminProductBundleCreationTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminProductBundleCreationTest.xml index 70fe7720f0d78..17235c531de8f 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminProductBundleCreationTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminProductBundleCreationTest.xml @@ -23,7 +23,7 @@ <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> - + <magentoCron stepKey="runCronIndex" groups="index"/> <!-- Admin Login--> <actionGroup stepKey="loginToAdminPanel" ref="AdminLoginActionGroup"/> </before> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml index c292d831fac13..ab1d4bb5ce68a 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml @@ -22,6 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!-- Delete the bundled product we created in the test body --> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultVideoBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultVideoBundleProductTest.xml index 09297a4e1df80..06ddd43d0e2cc 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultVideoBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultVideoBundleProductTest.xml @@ -24,6 +24,7 @@ <before> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminShouldBeAbleToMassUpdateAttributesForBundleProductsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminShouldBeAbleToMassUpdateAttributesForBundleProductsTest.xml index 4172611d99b88..caf500762883c 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminShouldBeAbleToMassUpdateAttributesForBundleProductsTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminShouldBeAbleToMassUpdateAttributesForBundleProductsTest.xml @@ -34,6 +34,7 @@ <requiredEntity createDataKey="createBundleOption"/> <requiredEntity createDataKey="createSimpleProduct"/> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!-- Delete Simple Product --> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml index c14da7e1cbfd0..b8eef5c1b406f 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductFixedPricingTest.xml @@ -23,7 +23,7 @@ <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> - + <magentoCron stepKey="runCronIndex" groups="index"/> <!--Admin login--> <actionGroup stepKey="loginToAdminPanel" ref="AdminLoginActionGroup"/> </before> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml index d08ad8970e19f..b5812817b5640 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml @@ -20,6 +20,7 @@ <before> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> <actionGroup ref="AdminLoginActionGroup" stepKey="login"/> </before> <after> @@ -61,8 +62,14 @@ <argument name="price" value="Discount"/> <argument name="amount" value="50"/> </actionGroup> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="signUpNewUser"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <amOnPage url="{{StorefrontProductPage.url(BundleProduct.urlKey)}}" stepKey="goToStorefront"/> <waitForPageLoad stepKey="waitForStorefront"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml index a3e5c988717a7..ada91d068efcf 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml @@ -21,6 +21,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="login"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!-- Delete the bundled product --> @@ -76,8 +77,7 @@ <argument name="product" value="$$simpleProduct2$$"/> <argument name="currency" value="USD - US Dollar"/> </actionGroup> - <click stepKey="openMiniCart" selector="{{StorefrontMinicartSection.showCart}}"/> - <waitForPageLoad stepKey="waitForMiniCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="openMiniCart"/> <see stepKey="seeCartSubtotal" userInput="$12,300.00"/> </test> </tests> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/EnableDisableBundleProductStatusTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/EnableDisableBundleProductStatusTest.xml index ceea9e47af7ee..90619eeeadae9 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/EnableDisableBundleProductStatusTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/EnableDisableBundleProductStatusTest.xml @@ -23,6 +23,7 @@ <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> <!--Admin login--> <actionGroup stepKey="loginToAdminPanel" ref="AdminLoginActionGroup"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml index 6310f6497ac1e..fd94ca93b1600 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml @@ -24,6 +24,7 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> <createData entity="SimpleProduct2" stepKey="simpleProduct3"/> <createData entity="SimpleProduct2" stepKey="simpleProduct4"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!--Clear Filters--> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/NewProductsListWidgetBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/NewProductsListWidgetBundleProductTest.xml index 27369d38f0c35..cc2aeb0602d36 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/NewProductsListWidgetBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/NewProductsListWidgetBundleProductTest.xml @@ -23,6 +23,7 @@ <before> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleOptionsToCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleOptionsToCartTest.xml index 7ded8b300f82d..8e0197697e691 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleOptionsToCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleOptionsToCartTest.xml @@ -30,6 +30,7 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct8"/> <createData entity="SimpleProduct2" stepKey="simpleProduct9"/> <createData entity="SimpleProduct2" stepKey="simpleProduct10"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml index 1a40489387197..b3c542af7bbc9 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAddBundleProductWithZeroPriceToShoppingCartTest.xml @@ -70,8 +70,8 @@ <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="filterOrderById"> <argument name="orderId" value="$grabOrderNumber"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForAdminOrderPageLoad"/> + + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <scrollTo selector="{{AdminOrderTotalSection.subTotal}}" stepKey="scrollToOrderTotalSection"/> <see selector="{{AdminOrderTotalSection.subTotal}}" userInput="$0.00" stepKey="checkSubtotal"/> </test> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml index dc5344e91ec82..8e8df1f4f16f0 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml @@ -22,6 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> @@ -79,8 +80,7 @@ <waitForPageLoad stepKey="waitForElementAdded"/> <!-- Go to the shopping cart page and grab the value of the option title --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="onPageShoppingCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="onPageShoppingCart"/> <grabTextFrom selector="{{CheckoutCartProductSection.nthBundleOptionName('1')}}" stepKey="grabTotalBefore"/> <!-- Find the product that we just created using the product grid --> @@ -100,8 +100,7 @@ <see stepKey="assertSuccess2" selector="{{AdminProductMessagesSection.successMessage}}" userInput="You saved the product."/> <!-- Go to the shopping cart page and make sure the title has changed --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="onPageShoppingCart1"/> - <waitForPageLoad stepKey="waitForCartPageLoad1"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="onPageShoppingCart1"/> <grabTextFrom selector="{{CheckoutCartProductSection.nthBundleOptionName('1')}}" stepKey="grabTotalAfter"/> <assertNotEquals stepKey="assertNotEquals"> <actualResult type="string">{$grabTotalAfter}</actualResult> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml index 85be636ec269c..e6f8834336683 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml @@ -100,8 +100,7 @@ <see selector="{{StorefrontMessagesSection.success}}" userInput="You added {{BundleProduct.name}} to your shopping cart." stepKey="seeAddToCartSuccessMessage"/> <!-- Verify cart contents --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCart"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <see selector="{{StorefrontBundledSection.nthItemOptionsTitle('1')}}" userInput="Option One" stepKey="seeOption1"/> <see selector="{{StorefrontBundledSection.nthItemOptionsTitle('2')}}" userInput="Option Two" stepKey="seeOption2"/> <see selector="{{StorefrontBundledSection.nthItemOptionsTitle('3')}}" userInput="Option Three" stepKey="seeOption3"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml index 1adad0f1a4d80..966082739aa68 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml @@ -22,6 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="login"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="logout"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductDetailsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductDetailsTest.xml index 80681704533fc..786040d16b7e2 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductDetailsTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductDetailsTest.xml @@ -23,7 +23,7 @@ <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> - + <magentoCron stepKey="runCronIndex" groups="index"/> <!-- Admin Login--> <actionGroup stepKey="loginToAdminPanel" ref="AdminLoginActionGroup"/> <actionGroup ref="DisabledWYSIWYGActionGroup" stepKey="disableWYSIWYG"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml index 6e4835654e4c1..871bf71d1f876 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml @@ -25,6 +25,7 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> <createData entity="SimpleProduct2" stepKey="simpleProduct3"/> <createData entity="SimpleProduct2" stepKey="simpleProduct4"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!--Logging out--> @@ -35,8 +36,7 @@ <deleteData createDataKey="simpleProduct4" stepKey="deleteSimpleProduct4"/> </after> <!--Make category--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="goToCategoryPage"/> - <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="goToCategoryPage"/> <actionGroup ref="CreateCategoryActionGroup" stepKey="createASubcategory"> <argument name="categoryEntity" value="SimpleSubCategory"/> </actionGroup> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml index a5e0c0cc4658a..ffcf5ba35dce8 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml @@ -23,7 +23,7 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> - <magentoCLI command="cron:run --group=index" stepKey="runCronIndexer"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <!-- Delete the bundled product --> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml index 115b540e672f1..161d308044b4a 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml @@ -22,6 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> @@ -88,8 +89,7 @@ <waitForPageLoad stepKey="waitForElementAdded2"/> <!-- Go to the shopping cart page and edit the first product --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="onPageShoppingCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="onPageShoppingCart"/> <waitForElementVisible stepKey="waitForInfoDropdown" selector="{{CheckoutCartSummarySection.total}}"/> <waitForPageLoad stepKey="waitForCartPageLoad3"/> <grabTextFrom selector="{{CheckoutCartSummarySection.total}}" stepKey="grabTotalBefore"/> @@ -106,8 +106,7 @@ <waitForPageLoad stepKey="waitForElementAdded3"/> <!-- Go to the shopping cart page --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="onPageShoppingCart2"/> - <waitForPageLoad stepKey="waitForCartPageLoad2"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="onPageShoppingCart2"/> <!-- Assert that the options are both there and the proce no longer matches --> <see stepKey="assertBothOptions" selector="{{CheckoutCartProductSection.nthItemOption('2')}}" userInput="$$simpleProduct1.sku$$"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml index 8a0334f01dab2..add819e2d3f14 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml @@ -23,6 +23,7 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct1"/> <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> <createData entity="_defaultCategory" stepKey="createCategory"/> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontSortBundleProductsByPriceTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontSortBundleProductsByPriceTest.xml index 26321f269e6d2..1c7cb39d7746f 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontSortBundleProductsByPriceTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontSortBundleProductsByPriceTest.xml @@ -120,8 +120,8 @@ </actionGroup> <!-- Assert first bundle products in category product grid --> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertFirstBundleProduct"> - <argument name="product" value="$$createFirstBundleProduct$$"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertFirstBundleProduct"> + <argument name="productName" value="$$createFirstBundleProduct.name$$"/> </actionGroup> <actionGroup ref="AssertStorefrontElementVisibleActionGroup" stepKey="seePriceRangeFromForFirstBundleProduct"> <argument name="selector" value="{{StorefrontCategoryProductSection.priceFromByProductId($$createFirstBundleProduct.id$$)}}"/> @@ -133,8 +133,8 @@ </actionGroup> <!-- Assert second bundle products in category product grid --> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertSecondBundleProduct"> - <argument name="product" value="$$createSecondBundleProduct$$"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertSecondBundleProduct"> + <argument name="productName" value="$$createSecondBundleProduct.name$$"/> </actionGroup> <actionGroup ref="AssertStorefrontElementVisibleActionGroup" stepKey="seePriceRangeFromForSecondBundleProduct"> <argument name="selector" value="{{StorefrontCategoryProductSection.priceFromByProductId($$createSecondBundleProduct.id$$)}}"/> @@ -146,8 +146,8 @@ </actionGroup> <!-- Assert third bundle products in category product grid --> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertThirdBundleProduct"> - <argument name="product" value="$$createThirdBundleProduct$$"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertThirdBundleProduct"> + <argument name="productName" value="$$createThirdBundleProduct.name$$"/> </actionGroup> <actionGroup ref="AssertStorefrontElementVisibleActionGroup" stepKey="seePriceRangeFromForThirdBundleProduct"> <argument name="selector" value="{{StorefrontCategoryProductSection.priceFromByProductId($$createThirdBundleProduct.id$$)}}"/> diff --git a/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePriceTest.php b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePriceTest.php index b0519f1ebddba..5d06150d197a9 100644 --- a/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePriceTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundlePriceTest.php @@ -68,7 +68,8 @@ public function testModifyMeta() ]; $priceParams = [ 'imports' => [ - 'disabled' => 'ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked' + 'disabled' => 'ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['disabled' => false], ] ]; $priceMeta = [ diff --git a/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundleWeightTest.php b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundleWeightTest.php index 8c89a18c292f6..c826bba4dbabb 100644 --- a/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundleWeightTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Ui/DataProvider/Product/Form/Modifier/BundleWeightTest.php @@ -58,6 +58,7 @@ public function testModifyMeta() $weightParams = [ 'imports' => [ 'disabled' => 'ns = ${ $.ns }, index = ' . BundleWeight::CODE_WEIGHT_TYPE . ':checked', + '__disableTmpl' => ['disabled' => false], ] ]; $hasWeightParams = [ diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleAdvancedPricing.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleAdvancedPricing.php index 1b04bdc4f8104..312a812402e97 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleAdvancedPricing.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleAdvancedPricing.php @@ -34,7 +34,7 @@ public function __construct(ArrayManager $arrayManager) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -63,7 +63,7 @@ public function modifyMeta(array $meta) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -88,7 +88,8 @@ private function modifyMsrpMeta(array $meta) $meta, [ 'imports' => [ - 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked' + 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['disabled' => false], ] ] ); @@ -103,7 +104,8 @@ private function modifyMsrpMeta(array $meta) $meta, [ 'imports' => [ - 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked' + 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['disabled' => false], ] ] ); diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleCustomOptions.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleCustomOptions.php index 1a0e08bd07255..b25fad0a40677 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleCustomOptions.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleCustomOptions.php @@ -15,7 +15,7 @@ class BundleCustomOptions extends AbstractModifier { /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -55,6 +55,7 @@ public function modifyCustomOptionsButton(array $meta, $group, $container, $butt if (!empty($meta[$group]['children'][$container]['children'][$button])) { $meta[$group]['children'][$container]['children'][$button]['arguments']['data']['config']['imports'] = [ 'visible' => '!ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['visible' => false], ]; } return $meta; @@ -79,6 +80,7 @@ public function getErrorMessage($sortOrder) 'sortOrder' => $sortOrder, 'imports' => [ 'visible' => 'ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['visible' => false], ], ], ], @@ -87,7 +89,7 @@ public function getErrorMessage($sortOrder) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index 18f970069c3c9..5ff9e674acad9 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -319,6 +319,7 @@ protected function getBundleHeader() * Get Bundle Options structure * * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function getBundleOptions() { @@ -348,7 +349,8 @@ protected function getBundleOptions() 'component' => 'Magento_Ui/js/dynamic-rows/record', 'positionProvider' => 'product_bundle_container.position', 'imports' => [ - 'label' => '${ $.name }' . '.product_bundle_container.option_info.title:value' + 'label' => '${ $.name }' . '.product_bundle_container.option_info.title:value', + '__disableTmpl' => ['label' => false], ], ], ], @@ -381,6 +383,7 @@ protected function getBundleOptions() 'template' => 'ui/dynamic-rows/templates/default', 'provider' => 'product_form.product_form_data_source', 'dataProvider' => '${ $.dataScope }' . '.bundle_button_proxy', + '__disableTmpl' => ['dataProvider' => false], 'identificationDRProperty' => 'product_id', 'identificationProperty' => 'product_id', 'map' => [ @@ -395,9 +398,13 @@ protected function getBundleOptions() 'selection_price_value' => '', 'selection_qty' => '', ], - 'links' => ['insertData' => '${ $.provider }:${ $.dataProvider }'], + 'links' => [ + 'insertData' => '${ $.provider }:${ $.dataProvider }', + '__disableTmpl' => ['insertData' => false], + ], 'imports' => [ 'inputType' => '${$.provider}:${$.dataScope}.type', + '__disableTmpl' => ['inputType' => false], ], 'source' => 'product', ], @@ -619,9 +626,11 @@ protected function getBundleSelections() 'is_collection' => true, 'imports' => [ 'inputType' => '${$.parentName}:inputType', + '__disableTmpl' => ['inputType' => false], ], 'exports' => [ 'isDefaultValue' => '${$.parentName}:isDefaultValue.${$.index}', + '__disableTmpl' => ['isDefaultValue' => false], ], ], ], @@ -702,7 +711,8 @@ protected function getBundleSelections() 'validate-greater-than-zero' => true ], 'imports' => [ - 'isInteger' => '${ $.provider }:${ $.parentScope }.selection_qty_is_integer' + 'isInteger' => '${ $.provider }:${ $.parentScope }.selection_qty_is_integer', + '__disableTmpl' => ['isInteger' => false], ], ], ], @@ -723,6 +733,7 @@ protected function getBundleSelections() 'sortOrder' => 110, 'imports' => [ 'inputType' => '${$.parentName}:inputType', + '__disableTmpl' => ['inputType' => false], ], ], ], @@ -764,7 +775,8 @@ protected function getSelectionPriceValue() 'dataScope' => 'selection_price_value', 'value' => '0.00', 'imports' => [ - 'visible' => '!ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked' + 'visible' => '!ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['visible' => false], ], 'sortOrder' => 80, ], @@ -801,7 +813,8 @@ protected function getSelectionPriceType() ] ], 'imports' => [ - 'visible' => '!ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked' + 'visible' => '!ns = ${ $.ns }, index = ' . BundlePrice::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['visible' => false], ], 'sortOrder' => 90, ], diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePrice.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePrice.php index d7da7513c3aac..598b762c061a1 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePrice.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePrice.php @@ -71,7 +71,8 @@ public function modifyMeta(array $meta) $meta, [ 'imports' => [ - 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked' + 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['disabled' => false], ] ] ); @@ -86,7 +87,8 @@ public function modifyMeta(array $meta) $meta, [ 'imports' => [ - 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked' + 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_PRICE_TYPE . ':checked', + '__disableTmpl' => ['disabled' => false], ] ] ); diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleWeight.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleWeight.php index 83e045d3562cf..39e9b3d7b5cd4 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleWeight.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundleWeight.php @@ -30,7 +30,7 @@ public function __construct(ArrayManager $arrayManager) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -73,15 +73,16 @@ public function modifyMeta(array $meta) [ 'imports' => [ 'disabled' => 'ns = ${ $.ns }, index = ' . static::CODE_WEIGHT_TYPE . ':checked', + '__disableTmpl' => ['disabled' => false], ] ] ); - + return $meta; } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { diff --git a/app/code/Magento/Captcha/Test/Mftf/ActionGroup/AdminLoginWithCaptchaActionGroup.xml b/app/code/Magento/Captcha/Test/Mftf/ActionGroup/AdminLoginWithCaptchaActionGroup.xml index b84977ba4fcd8..8d09944576538 100644 --- a/app/code/Magento/Captcha/Test/Mftf/ActionGroup/AdminLoginWithCaptchaActionGroup.xml +++ b/app/code/Magento/Captcha/Test/Mftf/ActionGroup/AdminLoginWithCaptchaActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminLoginWithCaptchaActionGroup" extends="LoginAsAdmin"> + <actionGroup name="AdminLoginWithCaptchaActionGroup" extends="AdminLoginActionGroup"> <annotations> <description>EXTENDS: LoginAsAdmin. Fills in the Captcha field on the Backend Admin Login page.</description> </annotations> diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/AdminLoginWithCaptchaTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/AdminLoginWithCaptchaTest.xml index 962b788aa80bb..28253fb3c00ef 100644 --- a/app/code/Magento/Captcha/Test/Mftf/Test/AdminLoginWithCaptchaTest.xml +++ b/app/code/Magento/Captcha/Test/Mftf/Test/AdminLoginWithCaptchaTest.xml @@ -30,7 +30,7 @@ <magentoCLI command="config:set {{AdminCaptchaDefaultSymbolsConfigData.path}} {{AdminCaptchaDefaultSymbolsConfigData.value}}" stepKey="setDefaultCaptchaSymbols" /> <magentoCLI command="cache:clean config full_page" stepKey="cleanInvalidatedCaches"/> </after> - + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdminWithWrongCredentialsFirstAttempt"> <argument name="username" value="{{AdminUserWrongCredentials.username}}"/> <argument name="password" value="{{AdminUserWrongCredentials.password}}"/> @@ -54,17 +54,19 @@ <!-- Submit form with incorrect captcha --> <actionGroup ref="AdminLoginWithCaptchaActionGroup" stepKey="loginAsAdminWithIncorrectCaptcha"> - <argument name="adminUser" value="DefaultAdminUser" /> - <argument name="captcha" value="{{WrongCaptcha.value}}" /> + <argument name="username" value="{{DefaultAdminUser.username}}"/> + <argument name="password" value="{{DefaultAdminUser.password}}"/> + <argument name="captcha" value="{{WrongCaptcha.value}}"/> </actionGroup> <actionGroup ref="AssertMessageOnAdminLoginActionGroup" stepKey="seeIncorrectCaptchaErrorMessage"> - <argument name="message" value="Incorrect CAPTCHA." /> + <argument name="message" value="Incorrect CAPTCHA."/> </actionGroup> <actionGroup ref="AssertCaptchaVisibleOnAdminLoginFormActionGroup" stepKey="assertCaptchaVisibleAfterIncorrectCaptcha" /> <actionGroup ref="AdminLoginWithCaptchaActionGroup" stepKey="loginAsAdminWithCorrectCaptcha"> - <argument name="adminUser" value="DefaultAdminUser" /> - <argument name="captcha" value="{{PreconfiguredCaptcha.value}}" /> + <argument name="username" value="{{DefaultAdminUser.username}}"/> + <argument name="password" value="{{DefaultAdminUser.password}}"/> + <argument name="captcha" value="{{PreconfiguredCaptcha.value}}"/> </actionGroup> <actionGroup ref="AssertAdminSuccessLoginActionGroup" stepKey="verifyAdminLoggedIn" /> </test> diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml index 0fff28973fe61..bfea4e99996c3 100644 --- a/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml +++ b/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml @@ -24,6 +24,7 @@ <createData entity="ApiSimpleProduct" stepKey="createSimpleProduct"> <requiredEntity createDataKey="createCategory"/> </createData> + <magentoCron stepKey="runCronIndex" groups="index"/> </before> <after> <magentoCLI command="config:set checkout/options/guest_checkout 1" stepKey="enableGuestCheckout"/> @@ -37,7 +38,7 @@ <waitForPageLoad stepKey="waitForAddToCart"/> <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <waitForText userInput="You added $$createSimpleProduct.name$$ to your shopping cart." stepKey="waitForText"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout"/> <waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.email}}" stepKey="waitEmailFieldVisible"/> <fillField selector="{{StorefrontCustomerSignInPopupFormSection.email}}" userInput="{{Simple_US_Customer.email}}" stepKey="fillCustomerEmail"/> @@ -49,7 +50,7 @@ <waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaReload}}" stepKey="seeCaptchaReloadButton"/> <reloadPage stepKey="refreshPage"/> <waitForPageLoad stepKey="waitForPageLoad2"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart2"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart2"/> <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout2"/> <waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.email}}" stepKey="waitEmailFieldVisible2"/> <waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaField}}" stepKey="seeCaptchaField2"/> diff --git a/app/code/Magento/CardinalCommerce/Test/Mftf/Test/AdminCardinalCommerceSettingsHiddenTest.xml b/app/code/Magento/CardinalCommerce/Test/Mftf/Test/AdminCardinalCommerceSettingsHiddenTest.xml deleted file mode 100644 index 59f1c13621982..0000000000000 --- a/app/code/Magento/CardinalCommerce/Test/Mftf/Test/AdminCardinalCommerceSettingsHiddenTest.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCardinalCommerceSettingsHiddenTest"> - <annotations> - <stories value="Cardinal Commerce Settings"/> - <features value="CardinalCommerce"/> - <stories value="Configure CardinalCommerce"/> - <title value="CardinalCommerce settings hidden" /> - <description value="CardinalCommerce config shouldn't be visible if the 3D secure is disabled for Authorize.Net."/> - <severity value="MINOR"/> - </annotations> - <before> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <magentoCLI command="config:set three_d_secure/cardinal/enabled_authorizenet 1" stepKey="enableCardinalCommerce"/> - </before> - - <after> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - <magentoCLI command="config:set three_d_secure/cardinal/enabled_authorizenet 0" stepKey="disableCardinalCommerce"/> - </after> - - <amOnPage url="{{AdminThreeDSecurePage.url}}" stepKey="openCurrencyOptionsPage" /> - <conditionalClick dependentSelector="{{AdminCardinalCommerceSection.enabled}}" visible="false" selector="{{AdminCardinalCommerceSection.head}}" stepKey="openCollapsibleBlock"/> - <see selector="{{AdminCardinalCommerceSection.environment}}" userInput="Production" stepKey="seeEnvironmentProduction"/> - <selectOption selector="{{AdminCardinalCommerceSection.enabled}}" userInput="0" stepKey="disableCardinalCommerceOption"/> - <dontSeeElement selector="{{AdminCardinalCommerceSection.environment}}" stepKey="dontSeeEnvironmentProduction"/> - </test> -</tests> diff --git a/app/code/Magento/Catalog/Block/Product/ListProduct.php b/app/code/Magento/Catalog/Block/Product/ListProduct.php index 59f5cc1b53b26..76fcdfbf232e5 100644 --- a/app/code/Magento/Catalog/Block/Product/ListProduct.php +++ b/app/code/Magento/Catalog/Block/Product/ListProduct.php @@ -136,7 +136,14 @@ public function getLayer() */ public function getLoadedProductCollection() { - return $this->_getProductCollection(); + $collection = $this->_getProductCollection(); + + $categoryId = $this->getLayer()->getCurrentCategory()->getId(); + foreach ($collection as $product) { + $product->setData('category_id', $categoryId); + } + + return $collection; } /** diff --git a/app/code/Magento/Catalog/Model/Layer/FilterList.php b/app/code/Magento/Catalog/Model/Layer/FilterList.php index a7eba474c58d8..86a7d1fb61938 100644 --- a/app/code/Magento/Catalog/Model/Layer/FilterList.php +++ b/app/code/Magento/Catalog/Model/Layer/FilterList.php @@ -123,9 +123,9 @@ protected function getAttributeFilterClass(\Magento\Catalog\Model\ResourceModel\ { $filterClassName = $this->filterTypes[self::ATTRIBUTE_FILTER]; - if ($attribute->getFrontendInput() === 'price') { + if ($attribute->getAttributeCode() == 'price') { $filterClassName = $this->filterTypes[self::PRICE_FILTER]; - } elseif ($attribute->getBackendType() === 'decimal') { + } elseif ($attribute->getBackendType() == 'decimal') { $filterClassName = $this->filterTypes[self::DECIMAL_FILTER]; } diff --git a/app/code/Magento/Catalog/Model/Layout/DepersonalizePlugin.php b/app/code/Magento/Catalog/Model/Layout/DepersonalizePlugin.php index 50ef65520c87d..5edb148e501d5 100644 --- a/app/code/Magento/Catalog/Model/Layout/DepersonalizePlugin.php +++ b/app/code/Magento/Catalog/Model/Layout/DepersonalizePlugin.php @@ -1,55 +1,55 @@ <?php /** - * Depersonalize catalog session data - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Model\Layout; +use Magento\Catalog\Model\Session as CatalogSession; +use Magento\Framework\View\LayoutInterface; use Magento\PageCache\Model\DepersonalizeChecker; /** - * Class DepersonalizePlugin + * Depersonalize customer data. + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class DepersonalizePlugin { /** * @var DepersonalizeChecker */ - protected $depersonalizeChecker; + private $depersonalizeChecker; /** - * Catalog session - * - * @var \Magento\Catalog\Model\Session + * @var CatalogSession */ - protected $catalogSession; + private $catalogSession; /** * @param DepersonalizeChecker $depersonalizeChecker - * @param \Magento\Catalog\Model\Session $catalogSession + * @param CatalogSession $catalogSession */ public function __construct( DepersonalizeChecker $depersonalizeChecker, - \Magento\Catalog\Model\Session $catalogSession + CatalogSession $catalogSession ) { - $this->catalogSession = $catalogSession; $this->depersonalizeChecker = $depersonalizeChecker; + $this->catalogSession = $catalogSession; } /** - * After generate Xml + * Change sensitive customer data if the depersonalization is needed. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @param \Magento\Framework\View\LayoutInterface $result - * @return \Magento\Framework\View\LayoutInterface + * @param LayoutInterface $subject + * @return void */ - public function afterGenerateXml(\Magento\Framework\View\LayoutInterface $subject, $result) + public function afterGenerateElements(LayoutInterface $subject) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->catalogSession->clearStorage(); } - return $result; } } diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index a9907c1661bd8..fd59130db4bdf 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -725,9 +725,14 @@ public function getIdBySku($sku) */ public function getCategoryId() { + if ($this->hasData('category_id')) { + return $this->getData('category_id'); + } $category = $this->_registry->registry('current_category'); - if ($category && in_array($category->getId(), $this->getCategoryIds())) { - return $category->getId(); + $categoryId = $category ? $category->getId() : null; + if ($categoryId && in_array($categoryId, $this->getCategoryIds())) { + $this->setData('category_id', $categoryId); + return $categoryId; } return false; } diff --git a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php index 57d08916bcd40..89c550d4e0ab3 100644 --- a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php +++ b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php @@ -10,11 +10,22 @@ */ class Options implements \Magento\Framework\Data\OptionSourceInterface { + /** * @var array */ protected $options; + /** + * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory + */ + protected $collectionFactory; + + /** + * @var \Magento\Catalog\Model\ResourceModel\Product + */ + protected $product; + /** * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory $collectionFactory * @param \Magento\Catalog\Model\ResourceModel\Product $product @@ -36,13 +47,6 @@ public function toOptionArray() $this->options = $this->collectionFactory->create() ->setEntityTypeFilter($this->product->getTypeId()) ->toOptionArray(); - - array_walk( - $this->options, - function (&$option) { - $option['__disableTmpl'] = true; - } - ); } return $this->options; diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php index 657daca13055e..4711828d8f78d 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category/Collection.php @@ -5,8 +5,11 @@ */ namespace Magento\Catalog\Model\ResourceModel\Category; +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\Product\Visibility; use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\DB\Select; use Magento\Store\Model\ScopeInterface; /** @@ -68,6 +71,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac */ private $scopeConfig; + /** + * @var Visibility + */ + private $catalogProductVisibility; + /** * Constructor * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory @@ -82,6 +90,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig + * @param Visibility|null $catalogProductVisibility * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -96,7 +105,8 @@ public function __construct( \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\DB\Adapter\AdapterInterface $connection = null, - \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig = null + \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig = null, + Visibility $catalogProductVisibility = null ) { parent::__construct( $entityFactory, @@ -113,6 +123,8 @@ public function __construct( ); $this->scopeConfig = $scopeConfig ?: \Magento\Framework\App\ObjectManager::getInstance()->get(ScopeConfigInterface::class); + $this->catalogProductVisibility = $catalogProductVisibility ?: + \Magento\Framework\App\ObjectManager::getInstance()->get(Visibility::class); } /** @@ -122,7 +134,7 @@ public function __construct( */ protected function _construct() { - $this->_init(\Magento\Catalog\Model\Category::class, \Magento\Catalog\Model\ResourceModel\Category::class); + $this->_init(Category::class, \Magento\Catalog\Model\ResourceModel\Category::class); } /** @@ -259,6 +271,7 @@ protected function _loadProductCount() * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.UnusedLocalVariable) + * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function loadProductCount($items, $countRegular = true, $countAnchor = true) { @@ -310,34 +323,14 @@ public function loadProductCount($items, $countRegular = true, $countAnchor = tr if ($countAnchor) { // Retrieve Anchor categories product counts + $categoryIds = array_keys($anchor); + $countSelect = $this->getProductsCountQuery($categoryIds, (bool)$websiteId); + $categoryProductsCount = $this->_conn->fetchPairs($countSelect); foreach ($anchor as $item) { - if ($allChildren = $item->getAllChildren()) { - $bind = ['entity_id' => $item->getId(), 'c_path' => $item->getPath() . '/%']; - $select = $this->_conn->select(); - $select->from( - ['main_table' => $this->getProductTable()], - new \Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)') - )->joinInner( - ['e' => $this->getTable('catalog_category_entity')], - 'main_table.category_id=e.entity_id', - [] - )->where( - '(e.entity_id = :entity_id OR e.path LIKE :c_path)' - ); - if ($websiteId) { - $select->join( - ['w' => $this->getProductWebsiteTable()], - 'main_table.product_id = w.product_id', - [] - )->where( - 'w.website_id = ?', - $websiteId - ); - } - $item->setProductCount((int)$this->_conn->fetchOne($select, $bind)); - } else { - $item->setProductCount(0); - } + $productsCount = isset($categoriesProductsCount[$item->getId()]) + ? (int)$categoryProductsCount[$item->getId()] + : $this->getProductsCountFromCategoryTable($item, $websiteId); + $item->setProductCount($productsCount); } } return $this; @@ -513,4 +506,69 @@ public function getProductTable() } return $this->_productTable; } + + /** + * Get products count using catalog_category_entity table + * + * @param Category $item + * @param string $websiteId + * @return int + */ + private function getProductsCountFromCategoryTable(Category $item, string $websiteId): int + { + $productCount = 0; + + if ($item->getAllChildren()) { + $bind = ['entity_id' => $item->getId(), 'c_path' => $item->getPath() . '/%']; + $select = $this->_conn->select(); + $select->from( + ['main_table' => $this->getProductTable()], + new \Zend_Db_Expr('COUNT(DISTINCT main_table.product_id)') + )->joinInner( + ['e' => $this->getTable('catalog_category_entity')], + 'main_table.category_id=e.entity_id', + [] + )->where( + '(e.entity_id = :entity_id OR e.path LIKE :c_path)' + ); + if ($websiteId) { + $select->join( + ['w' => $this->getProductWebsiteTable()], + 'main_table.product_id = w.product_id', + [] + )->where( + 'w.website_id = ?', + $websiteId + ); + } + $productCount = (int)$this->_conn->fetchOne($select, $bind); + } + return $productCount; + } + + /** + * Get query for retrieve count of products per category + * + * @param array $categoryIds + * @param bool $addVisibilityFilter + * @return Select + */ + private function getProductsCountQuery(array $categoryIds, $addVisibilityFilter = true): Select + { + $categoryTable = $this->getTable('catalog_category_product_index'); + $select = $this->_conn->select() + ->from( + ['cat_index' => $categoryTable], + ['category_id' => 'cat_index.category_id', 'count' => 'count(cat_index.product_id)'] + ) + ->where('cat_index.category_id in (?)', \array_map('\intval', $categoryIds)); + if (true === $addVisibilityFilter) { + $select->where('cat_index.visibility in (?)', $this->catalogProductVisibility->getVisibleInSiteIds()); + } + if (count($categoryIds) > 1) { + $select->group('cat_index.category_id'); + } + + return $select; + } } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 41b3f9781c8a0..6e1efbc9db003 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1180,9 +1180,33 @@ protected function _getSelectCountSql(?Select $select = null, $resetLeftJoins = if ($resetLeftJoins) { $countSelect->resetJoinLeft(); } + + $this->removeEntityIdentifierFromGroupBy($countSelect); + return $countSelect; } + /** + * Using `entity_id` for `GROUP BY` causes COUNT() return {n} rows of value = 1 instead of 1 row of value {n} + * + * @param Select $select + * @throws \Zend_Db_Select_Exception + */ + private function removeEntityIdentifierFromGroupBy(Select $select): void + { + $originalGroupBy = $select->getPart(Select::GROUP); + + if (!is_array($originalGroupBy)) { + return; + } + + $groupBy = array_filter($originalGroupBy, function ($field) { + return false === strpos($field, $this->getIdFieldName()); + }); + + $select->setPart(Select::GROUP, $groupBy); + } + /** * Prepare statistics data * @@ -1735,7 +1759,9 @@ public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC) if ($attribute == 'price' && $storeId != 0) { $this->addPriceData(); if ($this->_productLimitationFilters->isUsingPriceIndex()) { - $this->getSelect()->order("price_index.min_price {$dir}"); + $this->getSelect()->order( + new \Zend_Db_Expr("price_index.min_price = 0, price_index.min_price {$dir}") + ); return $this; } } @@ -1768,30 +1794,19 @@ public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC) */ protected function _prepareProductLimitationFilters() { - if (isset( - $this->_productLimitationFilters['visibility'] - ) && !isset( - $this->_productLimitationFilters['store_id'] - ) - ) { + if (isset($this->_productLimitationFilters['visibility']) + && !isset($this->_productLimitationFilters['store_id'])) { $this->_productLimitationFilters['store_id'] = $this->getStoreId(); } - if (isset( - $this->_productLimitationFilters['category_id'] - ) && !isset( - $this->_productLimitationFilters['store_id'] - ) - ) { + + if (isset($this->_productLimitationFilters['category_id']) + && !isset($this->_productLimitationFilters['store_id'])) { $this->_productLimitationFilters['store_id'] = $this->getStoreId(); } - if (isset( - $this->_productLimitationFilters['store_id'] - ) && isset( - $this->_productLimitationFilters['visibility'] - ) && !isset( - $this->_productLimitationFilters['category_id'] - ) - ) { + + if (isset($this->_productLimitationFilters['store_id']) + && isset($this->_productLimitationFilters['visibility']) + && !isset($this->_productLimitationFilters['category_id'])) { $this->_productLimitationFilters['category_id'] = $this->_storeManager->getStore( $this->_productLimitationFilters['store_id'] )->getRootCategoryId(); @@ -1822,14 +1837,8 @@ protected function _productLimitationJoinWebsite() $filters['website_ids'], 'int' ); - } elseif (isset( - $filters['store_id'] - ) && (!isset( - $filters['visibility'] - ) && !isset( - $filters['category_id'] - )) && !$this->isEnabledFlat() - ) { + } elseif (isset($filters['store_id']) && !$this->isEnabledFlat() + && (!isset($filters['visibility']) && !isset($filters['category_id']))) { $joinWebsite = true; $websiteId = $this->_storeManager->getStore($filters['store_id'])->getWebsiteId(); $conditions[] = $this->getConnection()->quoteInto('product_website.website_id = ?', $websiteId, 'int'); @@ -1904,9 +1913,9 @@ protected function _productLimitationJoinPrice() /** * Join Product Price Table with left-join possibility * - * @see \Magento\Catalog\Model\ResourceModel\Product\Collection::_productLimitationJoinPrice() * @param bool $joinLeft * @return $this + * @see \Magento\Catalog\Model\ResourceModel\Product\Collection::_productLimitationJoinPrice() * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function _productLimitationPrice($joinLeft = false) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AddSimpleProductToCartActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AddSimpleProductToCartActionGroup.xml index 68a051c232338..b4f7571429151 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AddSimpleProductToCartActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AddSimpleProductToCartActionGroup.xml @@ -8,9 +8,9 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AddSimpleProductToCartActionGroup" deprecated="Avoid using super-ActionGroups. Use StorefrontOpenProductEntityPageActionGroup, StorefrontAddSimpleProductToCartActionGroup and StorefrontAssertProductAddedToCartResultMessageActionGroup"> + <actionGroup name="AddSimpleProductToCartActionGroup"> <annotations> - <description>Navigates to the Storefront Product page. Then adds the Product to the Cart. Validates that the Success Message is present and correct.</description> + <description>Only works on Storefront Product Page - Add Simple Product to Cart</description> </annotations> <arguments> <argument name="product" defaultValue="product"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSaveCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSaveCategoryActionGroup.xml index 535a08382aabb..95f11901c97f0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSaveCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminSaveCategoryActionGroup.xml @@ -10,6 +10,5 @@ <actionGroup name="AdminSaveCategoryActionGroup"> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryWithProducts"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see userInput="You saved the category." stepKey="seeSuccessMessage"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminCategorySaveSuccessMessageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminCategorySaveSuccessMessageActionGroup.xml new file mode 100644 index 0000000000000..ddc2a5d44acbd --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertAdminCategorySaveSuccessMessageActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertAdminCategorySaveSuccessMessageActionGroup"> + <annotations> + <description>Checks success message after category was saved.</description> + </annotations> + + <waitForElementVisible selector="{{AdminMessagesSection.success}}" time="30" stepKey="waitForElement"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the category." stepKey="seeSuccessMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductOnCategoryPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductOnCategoryPageActionGroup.xml deleted file mode 100644 index 4bd2c97af7afb..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductOnCategoryPageActionGroup.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AssertProductOnCategoryPageActionGroup" extends="StorefrontCheckCategorySimpleProductActionGroup"> - <annotations> - <description>DEPRECATED. Use AssertStorefrontProductIsPresentOnCategoryPageActionGroup. - EXTENDS:StorefrontCheckCategorySimpleProduct. Removes 'AssertProductPrice', 'moveMouseOverProduct', 'AssertAddToCart'</description> - </annotations> - <remove keyForRemoval="AssertProductPrice"/> - <remove keyForRemoval="moveMouseOverProduct"/> - <remove keyForRemoval="AssertAddToCart"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCategoriesPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml similarity index 58% rename from app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCategoriesPageActionGroup.xml rename to app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml index 7f41a0c4eb1a3..f0a4faeb68e4b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminOpenCategoriesPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertStorefrontNoProductsFoundActionGroup.xml @@ -7,8 +7,7 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminOpenCategoriesPageActionGroup"> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="onCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageLoad" after="onCategoryIndexPage"/> + <actionGroup name="AssertStorefrontNoProductsFoundActionGroup"> + <see userInput="We can't find products matching the selection." stepKey="seeEmptyNotice"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteProductAttributeByLabelActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteProductAttributeByLabelActionGroup.xml deleted file mode 100644 index 15c3d55fb9382..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DeleteProductAttributeByLabelActionGroup.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="DeleteProductAttributeByLabelActionGroup"> - <annotations> - <description>DEPRECATED. Please use AdminDeleteProductAttributeByLabelActionGroup instead. Goes to the Admin Product Attributes grid page. Filters the grid for the provided Product Attribute (Label). Deletes the Product Attribute from the grid. Validates that the Success Message is present.</description> - </annotations> - <arguments> - <argument name="ProductAttribute"/> - </arguments> - - <amOnPage url="{{AdminProductAttributeGridPage.url}}" stepKey="navigateToProductAttributeGrid"/> - <fillField selector="{{AdminProductAttributeGridSection.FilterByAttributeCode}}" userInput="{{ProductAttribute.default_label}}" stepKey="setAttributeCode"/> - <click selector="{{AdminProductAttributeGridSection.Search}}" stepKey="searchForAttributeFromTheGrid"/> - <click selector="{{AdminProductAttributeGridSection.FirstRow}}" stepKey="clickOnAttributeRow"/> - <waitForPageLoad stepKey="waitForPageLoad"/> - <click selector="{{AttributePropertiesSection.DeleteAttribute}}" stepKey="deleteAttribute"/> - <click selector="{{ModalConfirmationSection.OkButton}}" stepKey="ClickOnDeleteButton"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> - <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="waitForSuccessMessage"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SaveCategoryFormActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SaveCategoryFormActionGroup.xml deleted file mode 100644 index 19f11a2402f56..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/SaveCategoryFormActionGroup.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="SaveCategoryFormActionGroup"> - <annotations> - <description>DEPRECATED. Use AdminSaveCategoryFormActionGroup instead. Requires navigation to the Category creation/edit page. Checks that the url contains the AdminCategoryPage url. Saves the Category.</description> - </annotations> - - <seeInCurrentUrl url="{{AdminCategoryPage.url}}" stepKey="seeOnCategoryPage"/> - <click selector="{{AdminMainActionsSection.save}}" stepKey="saveCategory"/> - <seeElement selector="{{AdminMessagesSection.success}}" stepKey="assertSuccess"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertNotExistProductInRecentlyComparedWidgetActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertNotExistProductInRecentlyComparedWidgetActionGroup.xml new file mode 100644 index 0000000000000..800685861ea3b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertNotExistProductInRecentlyComparedWidgetActionGroup.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!-- Check the product not exist in recently compared widget --> + <actionGroup name="StorefrontAssertNotExistProductInRecentlyComparedWidgetActionGroup"> + <annotations> + <description>Validate that the provided Product does not appear in the Recently Compared Products widget.</description> + </annotations> + <arguments> + <argument name="product"/> + </arguments> + + <waitForElementVisible selector="{{StorefrontWidgetsSection.widgetRecentlyComparedProductsGrid}}" stepKey="waitLoadingRecentlyComparedProductsGrid"/> + <dontSee selector="{{StorefrontWidgetsSection.widgetRecentlyComparedProductsGrid}}" userInput="{{product.name}}" stepKey="dontSeeProductInRecentlyComparedWidget"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertProductAbsentOnCategoryPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertProductAbsentOnCategoryPageActionGroup.xml deleted file mode 100644 index 0effec5329cc0..0000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertProductAbsentOnCategoryPageActionGroup.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="StorefrontAssertProductAbsentOnCategoryPageActionGroup"> - <annotations> - <description>DEPRECATED. Please use AssertStorefrontProductAbsentOnCategoryPageActionGroup instead. - Navigate to category page and verify product is absent.</description> - </annotations> - <arguments> - <argument name="category" defaultValue="_defaultCategory"/> - <argument name="product" defaultValue="SimpleProduct"/> - </arguments> - <amOnPage url="{{StorefrontCategoryPage.url(category.name)}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad stepKey="waitForCategoryPageLoad"/> - <dontSee selector="{{StorefrontCategoryMainSection.productName}}" userInput="{{product.name}}" stepKey="assertProductIsNotPresent"/> - <dontSee selector="{{StorefrontCategoryMainSection.productPrice}}" userInput="{{product.price}}" stepKey="assertProductIsNotPricePresent"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml index be04c297cec25..f3ccc00192a43 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogStorefrontConfigData.xml @@ -69,4 +69,12 @@ <data key="path">catalog/frontend/grid_per_page_values</data> <data key="value">1,2</data> </entity> + <entity name="DefaultGridPerPageDefaultConfigData"> + <data key="path">catalog/frontend/grid_per_page</data> + <data key="value">12</data> + </entity> + <entity name="CustomGridPerPageDefaultConfigData"> + <data key="path">catalog/frontend/grid_per_page</data> + <data key="value">1</data> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeData.xml index a2561e00a0e24..ffee02080503e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductAttributeData.xml @@ -282,28 +282,6 @@ <data key="used_for_sort_by">false</data> <requiredEntity type="FrontendLabel">ProductAttributeFrontendLabel</requiredEntity> </entity> - <entity name="productAttributeTypeOfPrice" type="ProductAttribute"> - <data key="attribute_code" unique="suffix">attribute</data> - <data key="frontend_input">price</data> - <data key="scope">global</data> - <data key="is_required">false</data> - <data key="is_unique">false</data> - <data key="is_searchable">false</data> - <data key="is_visible">true</data> - <data key="is_wysiwyg_enabled">false</data> - <data key="is_visible_in_advanced_search">false</data> - <data key="is_visible_on_front">true</data> - <data key="is_filterable">true</data> - <data key="is_filterable_in_search">false</data> - <data key="used_in_product_listing">false</data> - <data key="is_used_for_promo_rules">false</data> - <data key="is_comparable">true</data> - <data key="is_used_in_grid">false</data> - <data key="is_visible_in_grid">false</data> - <data key="is_filterable_in_grid">false</data> - <data key="used_for_sort_by">false</data> - <requiredEntity type="FrontendLabel">ProductAttributeFrontendLabel</requiredEntity> - </entity> <entity name="textProductAttribute" extends="productAttributeWysiwyg" type="ProductAttribute"> <data key="frontend_input">text</data> <data key="default_value" unique="suffix">defaultValue</data> diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryFilterSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryFilterSection.xml index faee605e77319..ddec4428f90e2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryFilterSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategoryFilterSection.xml @@ -11,6 +11,5 @@ <section name="StorefrontCategoryFilterSection"> <element name="CategoryFilter" type="button" selector="//main//div[@class='filter-options']//div[contains(text(), 'Category')]"/> <element name="CategoryByName" type="button" selector="//main//div[@class='filter-options']//li[@class='item']//a[contains(text(), '{{var1}}')]" parameterized="true"/> - <element name="CustomPriceAttribute" type="button" selector="div.filter-options-title"/> </section> </sections> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddToCartCrossSellTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddToCartCrossSellTest.xml index 83a05fef83607..e00b3fe2994eb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddToCartCrossSellTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddToCartCrossSellTest.xml @@ -77,8 +77,7 @@ </actionGroup> <!-- Check that cart page contains cross-sell to simpleProduct2 and simpleProduct3--> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart1"/> - <waitForPageLoad stepKey="waitForCartToLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart1"/> <waitForElementVisible selector="{{CheckoutCartCrossSellSection.products}}" stepKey="waitForCrossSellLoading"/> <see stepKey="seeProduct2InCrossSell" selector="{{CheckoutCartCrossSellSection.products}}" userInput="$simpleProduct2.name$"/> <see stepKey="seeProduct3InCrossSell" selector="{{CheckoutCartCrossSellSection.products}}" userInput="$simpleProduct3.name$"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageForCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageForCategoryTest.xml index dcb900164eba7..e4cf255a03e05 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageForCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageForCategoryTest.xml @@ -34,7 +34,7 @@ <argument name="categoryEntity" value="SimpleSubCategory"/> </actionGroup> <actionGroup ref="AddCategoryImageActionGroup" stepKey="addCategoryImage"/> - <actionGroup ref="SaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> + <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> <!-- Verify category with image in admin --> <actionGroup ref="CheckCategoryImageInAdminActionGroup" stepKey="checkCategoryImageInAdmin"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGCatalogTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGCatalogTest.xml index 1850faebd16c6..6eb4de39726f0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGCatalogTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddImageToWYSIWYGCatalogTest.xml @@ -22,8 +22,7 @@ <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84373"/> </annotations> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToNewCatalog"/> - <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToNewCatalog"/> <waitForLoadingMaskToDisappear stepKey="wait2" /> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SimpleSubCategory.name}}" stepKey="enterCategoryName"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml index 4aa96c91eb299..52da8c70a3bc8 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml @@ -83,7 +83,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <seeElement selector="{{StorefrontProductPageSection.successMsg}}" stepKey="seeSuccessSaveMessage"/> <seeElement selector="{{StorefrontMinicartSection.quantity(1)}}" stepKey="seeAddedProductQuantityInCart"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{SimpleProduct.name}}" stepKey="seeProductNameInMiniCart"/> <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{SimpleProduct.price}}" stepKey="seeProductPriceInMiniCart"/> <seeElement selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="seeCheckOutButtonInMiniCart"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml index b2181164070dc..cbbd496e8cb34 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminApplyTierPriceToProductTest/AdminApplyTierPriceToProductTest.xml @@ -171,8 +171,7 @@ <fillField selector="{{AdminProductFormAdvancedPricingSection.productTierPricePercentageValuePriceInput('1')}}" userInput="25" stepKey="selectProductTierPricePercentageValue2"/> <click selector="{{AdminProductFormAdvancedPricingSection.doneButton}}" stepKey="clickDoneButton4"/> <actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct4"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage1"/> - <waitForPageLoad time="30" stepKey="waitForShoppingCartPagePageLoad1"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage1"/> <seeInField userInput="20" selector="{{CheckoutCartProductSection.ProductQuantityByName($$createSimpleProduct.name$$)}}" stepKey="seeInQtyField20"/> <grabTextFrom selector="{{CheckoutCartProductSection.productSubtotalByName($$createSimpleProduct.name$$)}}" stepKey="grabTextFromSubtotalField4"/> <assertEquals message="Shopping cart should contain subtotal $1,500" stepKey="assertSubtotalField4"> @@ -198,8 +197,7 @@ <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig1"/> <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeConfigSuccessMessage1"/> <actionGroup ref="ClearCacheActionGroup" stepKey="flushCache1"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage2"/> - <waitForPageLoad time="30" stepKey="waitForShoppingCartPagePageLoad2"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage2"/> <seeInField userInput="20" selector="{{CheckoutCartProductSection.ProductQuantityByName($$createSimpleProduct.name$$)}}" stepKey="seeInQtyField20_2"/> <grabTextFrom selector="{{CheckoutCartProductSection.productSubtotalByName($$createSimpleProduct.name$$)}}" stepKey="grabTextFromSubtotalField5"/> <assertEquals message="Shopping cart should contain subtotal $1,500" stepKey="assertSubtotalField5"> @@ -212,8 +210,7 @@ <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig2"/> <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeConfigSuccessMessage2"/> <actionGroup ref="ClearCacheActionGroup" stepKey="flushCache2"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage3"/> - <waitForPageLoad time="30" stepKey="waitForShoppingCartPagePageLoad3"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage3"/> <seeInField userInput="20" selector="{{CheckoutCartProductSection.ProductQuantityByName($$createSimpleProduct.name$$)}}" stepKey="seeInQtyField20_3"/> <grabTextFrom selector="{{CheckoutCartProductSection.productSubtotalByName($$createSimpleProduct.name$$)}}" stepKey="grabTextFromSubtotalField6"/> <assertEquals message="Shopping cart should contain subtotal $1,500" stepKey="assertSubtotalField6"> @@ -250,8 +247,7 @@ <waitForElementVisible selector="{{AdminProductFormSection.productPrice}}" stepKey="waitForAdminProductFormSectionProductPriceInput"/> <fillField selector="{{AdminProductFormSection.productPrice}}" userInput="200" stepKey="fillProductPrice200"/> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage4"/> - <waitForPageLoad time="30" stepKey="waitForShoppingCartPagePageLoad4"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage4"/> <grabTextFrom selector="{{CheckoutCartProductSection.productSubtotalByName($$createSimpleProduct.name$$)}}" stepKey="grabTextFromSubtotalField7"/> <assertEquals message="Shopping cart should contain subtotal $4,000" stepKey="assertSubtotalField7"> <expectedResult type="string">$4,000.00</expectedResult> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml index 2640ab04023a3..96d0c209aba34 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml @@ -41,8 +41,7 @@ </actionGroup> <!-- Go to the cart page and verify we see the product --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="gotoCart"/> - <waitForPageLoad stepKey="waitForCartLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="gotoCart"/> <actionGroup ref="AssertStorefrontCheckoutCartItemsActionGroup" stepKey="assertProductItemInCheckOutCart"> <argument name="productName" value="$$createProduct.name$$"/> <argument name="productSku" value="$$createProduct.sku$$"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveAndNotIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveAndNotIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml index f076f4fa407b4..de8110f995606 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveAndNotIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveAndNotIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml @@ -30,8 +30,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Create subcategory under parent category --> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveCategoryAndSubcategoryIsNotVisibleInNavigationMenuTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveCategoryAndSubcategoryIsNotVisibleInNavigationMenuTest.xml index 8a0b1977bf901..fd8093d8d3b52 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveCategoryAndSubcategoryIsNotVisibleInNavigationMenuTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveCategoryAndSubcategoryIsNotVisibleInNavigationMenuTest.xml @@ -29,8 +29,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Create subcategory under parent category --> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml index e832f2baf24a2..e6cbe156698e7 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckInactiveIncludeInMenuCategoryAndSubcategoryIsNotVisibleInNavigationTest.xml @@ -30,8 +30,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Create subcategory under parent category --> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckMediaRolesForFirstAddedImageViaApiTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckMediaRolesForFirstAddedImageViaApiTest.xml index dfde5779637a4..b5ccd62401c9b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckMediaRolesForFirstAddedImageViaApiTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckMediaRolesForFirstAddedImageViaApiTest.xml @@ -27,7 +27,7 @@ <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> </after> <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToSimpleProduct"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml index 278a1fdc7ad9c..6ac71c4a7982d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckPaginationInStorefrontTest.xml @@ -99,8 +99,7 @@ <seeInField selector="{{AdminCatalogStorefrontConfigSection.productsPerPageDefaultValue}}" userInput="12" stepKey="seeDefaultValueProductPerPage"/> <!--Open Category Page and select created category--> <comment userInput="Open Category Page and select created category" stepKey="commentOpenCategoryPage"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForPageToLoad0"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(_defaultCategory.name)}}" stepKey="selectCreatedCategory"/> @@ -123,7 +122,7 @@ <click selector="{{AdminCategoryProductsGridSection.productSelectAll}}" stepKey="selectSelectAll"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <waitForPageLoad stepKey="waitForPageTitleToBeSaved"/> <!--Open Category Store Front Page--> <comment userInput="Open Category Store Front Page" stepKey="commentOpenCategoryOnStorefront"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckProductListPriceAttributesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckProductListPriceAttributesTest.xml index c389d447feeba..27b8b06510ee1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckProductListPriceAttributesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckProductListPriceAttributesTest.xml @@ -33,7 +33,7 @@ <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> </after> <actionGroup ref="ToggleAdminProductGridColumnsDropdownActionGroup" stepKey="openColumnsDropdown"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckSubCategoryIsNotVisibleInNavigationMenuTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckSubCategoryIsNotVisibleInNavigationMenuTest.xml index ff1e65bca9acc..192bab7c6d126 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckSubCategoryIsNotVisibleInNavigationMenuTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckSubCategoryIsNotVisibleInNavigationMenuTest.xml @@ -29,8 +29,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Create subcategory under parent category --> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml index a4414901517b9..85378ecfb76a9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminConfigureProductImagePlaceholderTest.xml @@ -114,7 +114,7 @@ <seeElement selector="{{StorefrontProductMediaSection.imageFile(placeholderBaseImage.name)}}" stepKey="seeBasePlaceholderImage"/> <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="addProductToCart1"/> <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" stepKey="waitForProductAdded1"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="openMiniCart1"/> <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$productNoImages.name$$)}}" userInput="src" stepKey="getThumbnailPlaceholderImageSrc"/> <assertContains stepKey="checkThumbnailPlaceholderImage"> <actualResult type="variable">$getThumbnailPlaceholderImageSrc</actualResult> @@ -132,7 +132,7 @@ <dontSeeElement selector="{{StorefrontProductMediaSection.imageFile(placeholderBaseImage.name)}}" stepKey="dontSeeBasePlaceholderImage"/> <click selector="{{StorefrontProductPageSection.addToCartBtn}}" stepKey="addProductToCart2"/> <waitForElementVisible selector="{{StorefrontProductPageSection.successMsg}}" stepKey="waitForProductAdded2"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart2"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="openMiniCart2"/> <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$productWithImages.name$$)}}" userInput="src" stepKey="getThumbnailImageSrc"/> <assertNotContains stepKey="checkThumbnailImage"> <actualResult type="variable">$getThumbnailImageSrc</actualResult> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCategoryFormDisplaySettingsUIValidationTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCategoryFormDisplaySettingsUIValidationTest.xml index e0fa4a3c3410c..c282cccb72952 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCategoryFormDisplaySettingsUIValidationTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCategoryFormDisplaySettingsUIValidationTest.xml @@ -23,8 +23,7 @@ <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SimpleSubCategory.name}}" stepKey="enterCategoryName"/> <click selector="{{CategoryDisplaySettingsSection.DisplaySettingTab}}" stepKey="clickOnDisplaySettingsTab"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminConfigDefaultCategoryLayoutFromConfigurationSettingTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminConfigDefaultCategoryLayoutFromConfigurationSettingTest.xml index e8b13afc7138e..900b3f6cd2f1c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminConfigDefaultCategoryLayoutFromConfigurationSettingTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminConfigDefaultCategoryLayoutFromConfigurationSettingTest.xml @@ -31,8 +31,7 @@ <seeOptionIsSelected selector="{{DefaultLayoutsSection.categoryLayout}}" userInput="No layout updates" stepKey="seeNoLayoutUpdatesSelected"/> <selectOption selector="{{DefaultLayoutsSection.categoryLayout}}" userInput="2 columns with right bar" stepKey="select2ColumnsLayout"/> <click selector="{{ContentManagementSection.Save}}" stepKey="clickSaveConfig"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToNewCatalog"/> - <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToNewCatalog"/> <waitForLoadingMaskToDisappear stepKey="wait2"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> <click selector="{{CategoryDesignSection.DesignTab}}" stepKey="clickOnDesignTab"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCreateCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCreateCategoryTest.xml index 8ad76bdde7306..b8e58eae8a98a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCreateCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest/AdminCreateCategoryTest.xml @@ -22,8 +22,7 @@ </after> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SimpleSubCategory.name}}" stepKey="enterCategoryName"/> <click selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="openSEO"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithAnchorFieldTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithAnchorFieldTest.xml index 7deb79c66ff6d..4c1993eb803b3 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithAnchorFieldTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithAnchorFieldTest.xml @@ -29,8 +29,7 @@ <deleteData stepKey="deleteSimpleProduct" createDataKey="simpleProduct"/> </after> <!--Create SubCategory--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{_defaultCategory.name}}" stepKey="fillCategoryName"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="enableCategory"/> @@ -60,7 +59,7 @@ <click selector="{{AdminCategoryContentSection.productTableRow}}" stepKey="selectProductFromTableRow"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <waitForPageLoad stepKey="waitForPageTitleToBeSaved"/> <!--Verify the Category Title--> <see selector="{{AdminCategoryContentSection.categoryPageTitle}}" userInput="{{_defaultCategory.name}}" stepKey="seePageTitle" /> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithCustomRootCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithCustomRootCategoryTest.xml index 71167882d135d..4b0774d2307dd 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithCustomRootCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithCustomRootCategoryTest.xml @@ -31,8 +31,7 @@ </actionGroup> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Create Root Category--> <actionGroup ref="AdminCreateRootCategory" stepKey="createNewRootCategory"> <argument name="categoryEntity" value="NewRootCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithFiveNestingTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithFiveNestingTest.xml index c1df630685949..b27d9239c53e1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithFiveNestingTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithFiveNestingTest.xml @@ -22,8 +22,7 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminPanel"/> </before> <after> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="goToCategoryPage"/> - <waitForPageLoad time="60" stepKey="waitForCategoryPageLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="goToCategoryPage"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(FirstLevelSubCat.name)}}" stepKey="clickCategoryLink"/> <click selector="{{AdminCategoryMainActionsSection.DeleteButton}}" stepKey="clickDelete"/> <waitForElementVisible selector="{{AdminCategoryModalSection.message}}" stepKey="waitForConfirmationModal"/> @@ -36,8 +35,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!--Create Category with Five Nesting --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Create Nested First Category--> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="enableCategory"/> @@ -45,35 +43,35 @@ <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveFirstSubCategory"/> <waitForPageLoad stepKey="waitForSFirstSubCategorySaved"/> <!-- Verify success message --> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <!--Create Nested Second Sub Category--> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton1"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SecondLevelSubCat.name}}" stepKey="fillSecondSubCategoryName"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveSecondSubCategory"/> <waitForPageLoad stepKey="waitForSecondCategory"/> <!-- Verify success message --> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage1"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage1"/> <!--Create Nested Third Sub Category/>--> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton2"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{ThirdLevelSubCat.name}}" stepKey="fillThirdSubCategoryName"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveThirdSubCategory"/> <waitForPageLoad stepKey="waitForThirdCategorySaved"/> <!-- Verify success message --> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage2"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage2"/> <!--Create Nested fourth Sub Category />--> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton3"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{FourthLevelSubCat.name}}" stepKey="fillFourthSubCategoryName"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveFourthSubCategory"/> <waitForPageLoad stepKey="waitForFourthCategorySaved"/> <!-- Verify success message --> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage3"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage3"/> <!--Create Nested fifth Sub Category />--> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton4"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{FifthLevelCat.name}}" stepKey="fillFifthSubCategoryName"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveFifthLevelCategory"/> <waitForPageLoad stepKey="waitForFifthCategorySaved"/> <!-- Verify success message --> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage4"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage4"/> <amOnPage url="/{{FirstLevelSubCat.name}}/{{SecondLevelSubCat.name}}/{{ThirdLevelSubCat.name}}/{{FourthLevelSubCat.name}}/{{FifthLevelCat.name}}.html" stepKey="seeTheCategoryInStoreFrontPage"/> <waitForPageLoad time="60" stepKey="waitForStoreFrontPageLoad"/> <!--<Verify category displayed in store front page--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveCategoryTest.xml index 34714db67fbd6..a7dab57173377 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveCategoryTest.xml @@ -25,15 +25,14 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Create In active Category --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton"/> <click selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}" stepKey="disableCategory"/> <checkOption selector="{{AdminCategoryBasicFieldSection.IncludeInMenu}}" stepKey="enableIncludeInMenu"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{_defaultCategory.name}}" stepKey="fillCategoryName"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <see selector="{{AdminCategoryContentSection.categoryPageTitle}}" userInput="{{_defaultCategory.name}}" stepKey="seePageTitle" /> <dontSeeCheckboxIsChecked selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="dontCategoryIsChecked"/> <!--Verify InActive Category is created--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveIncludeInMenuTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveIncludeInMenuTest.xml index a11717c04ea8c..d3a766be2c99f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveIncludeInMenuTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithInactiveIncludeInMenuTest.xml @@ -25,15 +25,14 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!--Create Category with not included in menu Subcategory --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="enableCategory"/> <click selector="{{AdminCategoryBasicFieldSection.includeInMenuLabel}}" stepKey="disableIncludeInMenu"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{_defaultCategory.name}}" stepKey="fillCategoryName"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <waitForPageLoad stepKey="waitForPageSaved"/> <see selector="{{AdminCategoryContentSection.categoryPageTitle}}" userInput="{{_defaultCategory.name}}" stepKey="seePageTitle" /> <!--Verify Category is created/>--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithNoAnchorFieldTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithNoAnchorFieldTest.xml index ec3c7a26723c2..3273fb62e7d9c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithNoAnchorFieldTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithNoAnchorFieldTest.xml @@ -30,8 +30,7 @@ </after> <!--Create SubCategory--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{_defaultCategory.name}}" stepKey="fillCategoryName"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="enableCategory"/> @@ -62,7 +61,7 @@ </actionGroup> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <waitForPageLoad stepKey="waitForPageTitleToBeSaved"/> <!-- Get Category ID --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilterTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilterTest.xml index 99d0f88cf0e9a..0b269749c5dd6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilterTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithProductsGridFilterTest.xml @@ -58,8 +58,7 @@ <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveProduct"/> <waitForPageLoad stepKey="waitForProductSaved"/> <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Create sub category--> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="enableCategory"/> @@ -75,7 +74,7 @@ <click selector="{{AdminCategoryContentSection.productTableRow}}" stepKey="selectDefaultProductFromTableRow"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="WaitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="successMessageYouSavedTheCategory"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="successMessageYouSavedTheCategory"/> <!--Verify product with grid filter is not not visible--> <amOnPage url="{{StorefrontProductPage.url(defaultSimpleProduct.urlKey)}}" stepKey="seeOnProductPage"/> <waitForPageLoad stepKey="waitForStoreFrontProductPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithRequiredFieldsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithRequiredFieldsTest.xml index 871dd606c14db..19552ddaab729 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithRequiredFieldsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryWithRequiredFieldsTest.xml @@ -25,15 +25,14 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Create subcategory with required fields --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategoryButton"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{_defaultCategory.name}}" stepKey="fillCategoryName"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="enableCategory"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> <!-- Verify success message --> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <!-- Verify subcategory created with required fields --> <see selector="{{AdminCategoryContentSection.categoryPageTitle}}" userInput="{{_defaultCategory.name}}" stepKey="seePageTitle" /> <seeElement selector="{{AdminCategoryContentSection.activeCategoryInTree(_defaultCategory.name)}}" stepKey="seeCategoryInTree" /> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml index c3b86c99bbd67..1c12b048e96d0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml @@ -55,8 +55,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Select created category and make category inactive--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(CatNotActive.name)}}" stepKey="selectCreatedCategory"/> <waitForPageLoad stepKey="waitForCategoryPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml index affdbaf7b0eb7..ff30c46a51c3a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml @@ -55,8 +55,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Select created category and make category inactive--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="selectCreatedCategory"/> <waitForPageLoad stepKey="waitForCategoryPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml index 10e4d9f434be0..2b4437aed1bb2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml @@ -55,8 +55,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Select created category and disable Include In Menu option--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="selectCreatedCategory"/> <waitForPageLoad stepKey="waitForCategoryPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml index b959b961ef1ea..40ca511e1f7bc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryAndSubcategoriesTest.xml @@ -39,7 +39,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout2"/> </after> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="amOnAdminCategoryPage"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="amOnAdminCategoryPage"/> <scrollToTopOfPage stepKey="scrollToTopOfPage1"/> <waitForPageLoad stepKey="waitForPageLoad1"/> <!--Create new root category--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryRequiredFieldsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryRequiredFieldsTest.xml index a5556b076fef6..29c7bc6828662 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryRequiredFieldsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateRootCategoryRequiredFieldsTest.xml @@ -20,7 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="LoginToAdminPanel"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginToAdminPanel"/> </before> <after> <actionGroup ref="DeleteCategoryActionGroup" stepKey="deleteCategory"> @@ -29,13 +29,13 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout" /> </after> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="OpenAdminCatergoryIndexPage"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="OpenAdminCatergoryIndexPage"/> <click selector="{{AdminCategorySidebarActionSection.AddRootCategoryButton}}" stepKey="ClickOnAddRootButton"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{_defaultCategory.name}}" stepKey="FillCategoryField"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="EnableCheckOption"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="ClickSaveButton"/> <waitForPageLoad stepKey="WaitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="AssertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="AssertSuccessMessage"/> <seeCheckboxIsChecked selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="SeeCheckBoxisSelected"/> <seeInField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{_defaultCategory.name}}" stepKey="SeedFieldInput"/> </test> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceForGeneralGroupTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceForGeneralGroupTest.xml index 9305e9ed3fd49..5076ab2515332 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceForGeneralGroupTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceForGeneralGroupTest.xml @@ -96,8 +96,8 @@ <actionGroup ref="StorefrontNavigateCategoryPageActionGroup" stepKey="openCategoryPageOnFrontend"> <argument name="category" value="$categoryEntity$"/> </actionGroup> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="checkProductOnCategoryPage"> - <argument name="product" value="virtualProductGeneralGroup"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="checkProductOnCategoryPage"> + <argument name="productName" value="{{virtualProductGeneralGroup.name}}"/> </actionGroup> <!--Verify customer see updated virtual product with tier price on product storefront page --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryAssignedToStoreTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryAssignedToStoreTest.xml index 0396ab743c745..2fa91604e1776 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryAssignedToStoreTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryAssignedToStoreTest.xml @@ -39,8 +39,7 @@ <see userInput="You saved the store." stepKey="seeSaveMessage"/> <!--Verify Delete Root Category can not be deleted--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <scrollToTopOfPage stepKey="scrollToTopOfPage2"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandToSeeAllCategories"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(NewRootCategory.name))}}" stepKey="clickRootCategoryInTree"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryTest.xml index 0a41842d5709c..40bd3bdcfea20 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootCategoryTest.xml @@ -26,8 +26,7 @@ </after> <!--Verify Created root Category--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandToSeeAllCategories"/> <waitForPageLoad stepKey="waitForPageToLoad"/> <seeElement selector="{{AdminCategoryBasicFieldSection.CategoryNameInput(NewRootCategory.name)}}" stepKey="seeRootCategory"/> @@ -36,8 +35,7 @@ <deleteData createDataKey="rootCategory" stepKey="deleteRootCategory"/> <!--Verify Root Category is not listed in backend--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandToSeeAllCategories1"/> <dontSee selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{NewRootCategory.name}}" stepKey="dontSeeRootCategory"/> </test> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootSubCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootSubCategoryTest.xml index 6ae00d213bf77..fe07360d6b9ca 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootSubCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteRootSubCategoryTest.xml @@ -70,8 +70,7 @@ <deleteData createDataKey="category" stepKey="deleteCategory"/> <!--Verify Sub Category is absent in backend --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryIndexPageToBeLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandToSeeAllCategories2"/> <dontSee selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleRootSubCategory.name)}}" stepKey="dontSeeCategoryInTree"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml index 89b3b2cb6fb41..2b198dacca241 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminFilteringCategoryProductsUsingScopeSelectorTest.xml @@ -100,7 +100,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Step 1-2: Open Category page and Set scope selector to All Store Views--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="goToCategoryPage"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="goToCategoryPage"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree($$createCategory.name$$)}}" stepKey="clickCategoryName"/> <click selector="{{AdminCategoryProductsSection.sectionHeader}}" stepKey="openProductSection"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryTest.xml index d302dad52d6e6..44a7dc4102e4f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryTest.xml @@ -30,11 +30,7 @@ <createData entity="_defaultProduct" stepKey="productTwo"> <requiredEntity createDataKey="simpleSubCategoryOne"/> </createData> - - <!-- TODO: Replace this with CliRunReindexUsingCronJobsActionGroup after MC-29943 delivered--> - <magentoCLI command="cron:run" arguments="--group='index'" stepKey="firstRunToScheduleJobs"/> - <magentoCLI command="cron:run" arguments="--group='index'" stepKey="secondRunToExecuteJobs"/> - + <magentoCron groups="index" stepKey="RunToScheduleJobs"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> @@ -48,8 +44,7 @@ </after> <!--Move category one to category two--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToAdminCategoryPage"/> - <waitForPageLoad stepKey="waitForAdminCategoryPageLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToAdminCategoryPage"/> <actionGroup ref="MoveCategoryActionGroup" stepKey="moveSimpleSubCategoryOneToSimpleSubCategoryTwo"> <argument name="childCategory" value="$simpleSubCategoryOne.name$"/> <argument name="parentCategory" value="$simpleSubCategoryTwo.name$"/> @@ -89,8 +84,7 @@ <see selector="{{StorefrontNavigationSection.breadcrumbs}}" userInput="$simpleSubCategoryOne.name$" stepKey="seeSubCategoryWithParentInBreadcrumbsOnSubCategoryWithParent"/> <see selector="{{StorefrontNavigationSection.breadcrumbs}}" userInput="$productOne.name$" stepKey="seeProductInBreadcrumbsOnSubCategoryWithParent"/> <!--Move category one to the same level as category two--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToAdminCategoryPage2"/> - <waitForPageLoad stepKey="waitForAdminCategoryPageLoad2"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToAdminCategoryPage2"/> <actionGroup ref="MoveCategoryActionGroup" stepKey="moveSimpleSubCategoryOneToDefaultCategory"> <argument name="childCategory" value="$simpleSubCategoryOne.name$"/> <argument name="parentCategory" value="Default Category"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryToDefaultCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryToDefaultCategoryTest.xml index 1ea1f60f52a2c..bf5fde3b85bba 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryToDefaultCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveAnchoredCategoryToDefaultCategoryTest.xml @@ -29,8 +29,7 @@ </after> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(_defaultCategory.name)}}" stepKey="selectCategory"/> @@ -92,8 +91,7 @@ <see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="{{defaultSimpleProduct.name}}" stepKey="assertProductName"/> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree2"/> <waitForPageLoad stepKey="waitForPageToLoad2"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryAndCheckUrlRewritesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryAndCheckUrlRewritesTest.xml index 39040c7e88205..4dbbdc8f4399e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryAndCheckUrlRewritesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryAndCheckUrlRewritesTest.xml @@ -32,8 +32,7 @@ </after> <!--Open category page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(FirstLevelSubCat.name)}}" stepKey="selectCategory"/> @@ -74,8 +73,7 @@ <see stepKey="verifyTheTargetPath" selector="{{AdminUrlRewriteIndexSection.gridCellByColumnRowNumber('1', 'Target Path')}}" userInput="catalog/category/view/id/{$categoryId}"/> <!--Open Category Page --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree2"/> <waitForPageLoad stepKey="waitForPageToLoad2"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml index 7fdc6e7b9cf8f..116df566f2bd0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml @@ -32,8 +32,7 @@ </after> <!--Open Category page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(_defaultCategory.name)}}" stepKey="selectCategory"/> @@ -81,8 +80,7 @@ <see selector="{{StorefrontProductInfoMainSection.productName}}" userInput="{{defaultSimpleProduct.name}}" stepKey="assertProductName"/> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree2"/> <waitForPageLoad stepKey="waitForPageToLoad2"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryToAnotherPositionInCategoryTreeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryToAnotherPositionInCategoryTreeTest.xml index 2909d17b1541b..fd9e50928d748 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryToAnotherPositionInCategoryTreeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryToAnotherPositionInCategoryTreeTest.xml @@ -32,8 +32,7 @@ </after> <!-- Open Category Page --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(_defaultCategory.name)}}" stepKey="selectCategory"/> @@ -68,8 +67,7 @@ </assertEquals> <!-- Move Category to another position in category tree and click ok button--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openTheAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitTillPageLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openTheAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <waitForPageLoad stepKey="waitForPageLoad"/> <dragAndDrop selector1="{{AdminCategorySidebarTreeSection.categoryInTree(SecondLevelSubCat.name)}}" selector2="{{AdminCategorySidebarTreeSection.categoryInTree('Default Category')}}" stepKey="DragCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml index afac68ae2b1b7..fe31456aca334 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveProductBetweenCategoriesTest.xml @@ -158,7 +158,7 @@ <!-- # Category should open successfully # <product1> should be absent on the page --> <see userInput="$$createAnchoredCategory1.name$$" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="seeCategory1Name"/> - <see userInput="We can't find products matching the selection." stepKey="seeEmptyNotice"/> + <actionGroup ref="AssertStorefrontNoProductsFoundActionGroup" stepKey="seeEmptyNotice"/> <dontSee userInput="$$simpleProduct.name$$" selector="{{StorefrontCategoryMainSection.productName}}" stepKey="dontseeProduct"/> <!-- Log in to the backend: Admin user is logged in--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml index b8e7bdae0df2b..eebd3472cbd95 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCategoryIndexerInUpdateOnScheduleModeTest.xml @@ -91,7 +91,7 @@ <!-- The category is still empty --> <see userInput="$$createCategoryA.name$$" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="seeCategoryA1Name"/> - <see userInput="We can't find products matching the selection." stepKey="seeEmptyNotice"/> + <actionGroup ref="AssertStorefrontNoProductsFoundActionGroup" stepKey="seeEmptyNotice"/> <dontSee userInput="$$createProductA1.name$$" selector="{{StorefrontCategoryMainSection.productName}}" stepKey="dontseeProductA1"/> <!-- 4. Run cron to reindex --> @@ -132,7 +132,7 @@ <!-- Category A is empty now --> <see userInput="$$createCategoryA.name$$" selector="{{StorefrontCategoryMainSection.CategoryTitle}}" stepKey="seeOnPageCategoryAName"/> - <see userInput="We can't find products matching the selection." stepKey="seeOnPageEmptyNotice"/> + <actionGroup ref="AssertStorefrontNoProductsFoundActionGroup" stepKey="seeOnPageEmptyNotice"/> <dontSee userInput="$$createProductA1.name$$" selector="{{StorefrontCategoryMainSection.productName}}" stepKey="dontseeProductA1OnPage"/> <!-- Case: change product status --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCustomURLKeyPreservedWhenAssignedToCategoryWithoutCustomURLKeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCustomURLKeyPreservedWhenAssignedToCategoryWithoutCustomURLKeyTest.xml index 6d197d19eb924..1c536df7c2efb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCustomURLKeyPreservedWhenAssignedToCategoryWithoutCustomURLKeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductCustomURLKeyPreservedWhenAssignedToCategoryWithoutCustomURLKeyTest.xml @@ -76,7 +76,7 @@ <argument name="productSku" value="$createSimpleProductSecond.sku$"/> </actionGroup> - <actionGroup ref="SaveCategoryFormActionGroup" stepKey="saveCategory"/> + <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategory"/> <executeJS function="return '$createCategory.name$'.toLowerCase();" stepKey="categoryNameLower" /> <executeJS function="return '$createSimpleProductFirst.name$'.toLowerCase();" stepKey="simpleProductFirstNameLower" /> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveImageFromCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveImageFromCategoryTest.xml index ee8636dece808..8033a2dffec7c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveImageFromCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveImageFromCategoryTest.xml @@ -34,12 +34,12 @@ <argument name="categoryEntity" value="SimpleSubCategory"/> </actionGroup> <actionGroup ref="AddCategoryImageActionGroup" stepKey="addCategoryImage"/> - <actionGroup ref="SaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> + <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategoryForm"/> <actionGroup ref="CheckCategoryImageInAdminActionGroup" stepKey="checkCategoryImageInAdmin"/> <!-- Remove image from category --> <actionGroup ref="RemoveCategoryImageActionGroup" stepKey="removeCategoryImage"/> - <actionGroup ref="SaveCategoryFormActionGroup" stepKey="saveCategoryFormAfterRemove"/> + <actionGroup ref="AdminSaveCategoryFormActionGroup" stepKey="saveCategoryFormAfterRemove"/> <actionGroup ref="CheckCategoryOnStorefrontActionGroup" stepKey="CheckCategoryOnStorefront"> <argument name="categoryEntity" value="SimpleSubCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml index 0281fded3a8e4..2444165fa1b39 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml @@ -22,7 +22,7 @@ </after> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage"/> <waitForElementVisible selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="waitForAddSubCategoryVisible"/> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndCheckDefaultUrlKeyOnStoreViewTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndCheckDefaultUrlKeyOnStoreViewTest.xml index f3225bcd7fe3d..e0e517defdeac 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndCheckDefaultUrlKeyOnStoreViewTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndCheckDefaultUrlKeyOnStoreViewTest.xml @@ -50,8 +50,7 @@ </actionGroup> <!--Update Category--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleRootSubCategory.name)}}" stepKey="selectCategory"/> <waitForPageLoad stepKey="waitForPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndMakeInactiveTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndMakeInactiveTest.xml index 2865e9bc87dd3..a4ba859714982 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndMakeInactiveTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryAndMakeInactiveTest.xml @@ -27,8 +27,7 @@ </after> <!--Open category page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Update category and make category inactive--> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> @@ -36,7 +35,7 @@ <click selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}" stepKey="disableCategory"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <see selector="{{AdminCategoryContentSection.categoryPageTitle}}" userInput="{{_defaultCategory.name}}" stepKey="seePageTitle" /> <dontSeeCheckboxIsChecked selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="dontCategoryIsChecked"/> @@ -47,8 +46,7 @@ <waitForPageLoad time="15" stepKey="wait"/> <!--Verify Inactive Category in category page --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForPageToLoaded1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree1"/> <seeElement selector="{{AdminCategoryContentSection.categoryInTree(_defaultCategory.name)}}" stepKey="assertCategoryInTree" /> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(_defaultCategory.name)}}" stepKey="selectCreatedCategory1"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryNameWithStoreViewTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryNameWithStoreViewTest.xml index 3c3baf3524e87..0ca8e74c4e59e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryNameWithStoreViewTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryNameWithStoreViewTest.xml @@ -57,8 +57,7 @@ <seeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SimpleRootSubCategory.name)}}" stepKey="seeCatergoryInStoreFront"/> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Update Category--> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandToSeeAllCategories"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml index 8b57c2e371355..87d7f91431dc3 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml @@ -27,8 +27,7 @@ <!-- Create category, change store view to default --> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage"/> <actionGroup ref="CreateCategoryActionGroup" stepKey="createCategory"> <argument name="categoryEntity" value="_defaultCategory"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml index 117019da38ffa..6a12b991bd225 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml @@ -59,8 +59,7 @@ <waitForPageLoad stepKey="waitForProductToLoad"/> <!--Update URL Key--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded2"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleRootSubCategory.name)}}" stepKey="selectCategory1"/> <scrollTo selector="{{AdminCategorySEOSection.SectionHeader}}" stepKey="scrollToSearchEngineOptimization"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithInactiveIncludeInMenuTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithInactiveIncludeInMenuTest.xml index 9663632e6dc36..db6cfce167bce 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithInactiveIncludeInMenuTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithInactiveIncludeInMenuTest.xml @@ -28,8 +28,7 @@ </after> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!--Update Category name,description, urlKey, meta title and disable Include in Menu--> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> @@ -47,7 +46,7 @@ <fillField selector="{{AdminCategorySEOSection.MetaTitleInput}}" userInput="{{SimpleRootSubCategory.name}}" stepKey="fillUpdatedMetaTitle"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <!--Open UrlRewrite Page--> <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="openUrlRewriteIndexPage"/> @@ -65,8 +64,7 @@ <seeElement selector="{{StorefrontCategoryMainSection.CategoryTitle(SimpleRootSubCategory.name)}}" stepKey="seeUpdatedCategoryInStoreFrontPage"/> <!--Verify Updated fields in Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForPageToLoaded1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree1"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleRootSubCategory.name)}}" stepKey="selectCreatedCategory1"/> <waitForPageLoad stepKey="waitForCategoryPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml index ccab2f9e96ce7..9b827550a6817 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryWithProductsTest.xml @@ -29,8 +29,7 @@ </after> <!--Open Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(_defaultCategory.name)}}" stepKey="selectCreatedCategory"/> <checkOption selector="{{AdminCategoryBasicFieldSection.EnableCategory}}" stepKey="enableCategory"/> @@ -58,7 +57,7 @@ <click selector="{{AdminCategoryContentSection.productTableRow}}" stepKey="selectProduct1FromTableRow"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the category." stepKey="assertSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <waitForPageLoad stepKey="waitForPageTitleToBeSaved"/> <!--Verify Category Title--> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml index 512df79cb7c9c..1950b385c4a68 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml @@ -58,8 +58,7 @@ </after> <!-- Select Created Category--> <magentoCLI command="indexer:reindex" stepKey="reindexBeforeFlow"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="selectCreatedCategory"/> <waitForPageLoad stepKey="waitForTheCategoryPageToLoaded"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryIncludeInNavigationTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryIncludeInNavigationTest.xml index f444e741fea0e..6ee1fd6a58e42 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryIncludeInNavigationTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryIncludeInNavigationTest.xml @@ -58,8 +58,7 @@ <waitForPageLoad time="60" stepKey="waitForPageToBeLoaded"/> <dontSee selector="{{StorefrontHeaderSection.NavigationCategoryByName(CatNotIncludeInMenu.name)}}" stepKey="dontSeeCategoryOnNavigation"/> <!-- Select created category and enable Include In Menu option--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(CatNotIncludeInMenu.name)}}" stepKey="selectCreatedCategory"/> <waitForPageLoad stepKey="waitForCategoryPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml index 2b9cbf379c5e6..dd79dd6824bbb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryNameAndDescriptionTest.xml @@ -55,8 +55,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Select Created Category--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(_defaultCategory.name)}}" stepKey="selectCreatedCategory"/> <waitForPageLoad stepKey="waitForPageToLoaded"/> @@ -89,8 +88,7 @@ <waitForPageLoad stepKey="waitForSecondStoreView"/> <seeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SimpleSubCategory.name)}}" stepKey="seeCategoryOnNavigation1"/> <!-- Verify Updated Category Name and description on Category Page--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage1"/> - <waitForPageLoad stepKey="waitForCategoryPageToLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage1"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree1"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="selectUpdatedCategory"/> <waitForPageLoad stepKey="waitForUpdatedCategoryPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml index 45f8918100083..4256f93ea41d1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml @@ -55,8 +55,7 @@ <see selector="{{AdminProductFormSection.successMessage}}" userInput="You saved the product." stepKey="seeAssertSimpleProductSaveSuccessMessage"/> <!--Search default simple product in the grid page --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="OpenCategoryCatalogPage"/> - <waitForPageLoad stepKey="waitForCategoryCatalogPage"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="OpenCategoryCatalogPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickExpandTree"/> <waitForPageLoad stepKey="waitForCategoryToLoad"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree($$initialCategoryEntity.name$$)}}" stepKey="selectCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml index c924c94a9aba8..855a2b1d9b0cc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml @@ -155,7 +155,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <seeElement selector="{{StorefrontProductPageSection.successMsg}}" stepKey="seeYouAddedSimpleprod4ToYourShoppingCartSuccessSaveMessage"/> <seeElement selector="{{StorefrontMinicartSection.quantity(1)}}" stepKey="seeAddedProductQuantityInCart"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{simpleProductRegularPriceCustomOptions.name}}" stepKey="seeProductNameInMiniCart"/> <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{simpleProductRegularPriceCustomOptions.storefront_new_cartprice}}" stepKey="seeProductPriceInMiniCart"/> </test> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithNoRedirectTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithNoRedirectTest.xml index db8b808e74f76..5221510fd4dce 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithNoRedirectTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithNoRedirectTest.xml @@ -40,8 +40,7 @@ </after> <!-- Open Category page --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!-- Open 3rd Level category --> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithRedirectTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithRedirectTest.xml index c5757a6428e8d..505ca583da3f4 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithRedirectTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateTopCategoryUrlWithRedirectTest.xml @@ -38,8 +38,7 @@ </after> <!-- Open Category page --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="openAdminCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForPageToLoaded"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openAdminCategoryIndexPage"/> <!-- Open 3rd Level category --> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="clickOnExpandTree"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml index cea09b0cdb4bd..595f9bcd489ec 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml index 77de42bdbac21..458d02d61426d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml index 918cda5274216..6d6ff0b3b1b89 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml index 5f6f44110bfb4..d5ae971d87695 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml index 393c280eedf1b..314df67d43d00 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml index 9658597a04717..d0f4fc8882e3f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml index 9d3d315487d65..2234d6f338b62 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryAndSearchTest.xml index f5571633c2da4..ab5d23f0f875e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryAndSearchTest.xml @@ -25,10 +25,8 @@ <requiredEntity createDataKey="initialCategoryEntity"/> </createData> <createData entity="SimpleSubCategory" stepKey="categoryEntity"/> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> - - <!-- TODO: Replace this with CliRunReindexUsingCronJobsActionGroup after MC-29943 delivered--> - <magentoCLI command="indexer:reindex" arguments="catalogsearch_fulltext catalog_category_product" stepKey="reindexIndices"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <magentoCron groups="index" stepKey="RunToScheduleJobs"/> </before> <after> @@ -110,8 +108,8 @@ <actionGroup ref="StorefrontNavigateCategoryPageActionGroup" stepKey="openCategoryPageOnFrontend"> <argument name="category" value="$categoryEntity$"/> </actionGroup> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="checkProductOnCategoryPage"> - <argument name="product" value="updateVirtualProductTierPriceInStock"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="checkProductOnCategoryPage"> + <argument name="productName" value="{{updateVirtualProductTierPriceInStock.name}}"/> </actionGroup> <!--Verify customer see updated virtual product with tier price on product storefront page --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml index 5c0b7c31756ca..8f0861fe33371 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml index eeb85e8d6fc2e..f7f5385381590 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="defaultVirtualProduct" stepKey="initialVirtualProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml index b0a3d02f31846..ce9ff3af18607 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml @@ -42,8 +42,7 @@ <deleteData createDataKey="createProduct3" stepKey="deleteProduct3"/> </after> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin1"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage1"/> - <waitForPageLoad time="30" stepKey="waitForPageCategoryLoadAfterNavigate"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage1"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree($$createNewRootCategoryA.name$$)}}" stepKey="openNewRootCategory"/> <waitForPageLoad stepKey="waitForPageCategoryLoadAfterClickOnNewRootCategory"/> <seeElement selector="{{AdminCategoryMainActionsSection.DeleteButton}}" stepKey="assertDeleteButtonIsPresent"/> @@ -79,8 +78,7 @@ <!--<magentoCLI command="indexer:reindex" stepKey="magentoCli"/>--> <!-- Delete Default Root Category. --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPageAfterCLIReindexCommand"/> - <waitForPageLoad time="30" stepKey="waitForPageCategoryLoadAfterCLIReindexCommand"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPageAfterCLIReindexCommand"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree('Default Category')}}" stepKey="clickOnDefaultRootCategory"/> <waitForPageLoad stepKey="waitForPageDefaultCategoryEditLoad" /> <seeElement selector="{{AdminCategoryMainActionsSection.DeleteButton}}" stepKey="assertDeleteButtonIsPresent1"/> @@ -122,8 +120,7 @@ <!--</actionGroup>--> <!-- Delete Categories 1(with subcategory) and 3. --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPageAfterStoreFrontCategoryAssertions"/> - <waitForPageLoad time="30" stepKey="waitForCategoryPageLoadAfterStoreFrontCategoryAssertions"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPageAfterStoreFrontCategoryAssertions"/> <actionGroup ref="DeleteCategoryActionGroup" stepKey="deleteCategoryC"> <argument name="categoryEntity" value="$$createCategoryC$$"/> </actionGroup> @@ -151,8 +148,7 @@ <argument name="product" value="$$createProduct3$$"/> </actionGroup> <!-- Rename New Root Category to Default category --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPageAfterStoreFrontProductsAssertions"/> - <waitForPageLoad time="30" stepKey="waitForCategoryPageLoadAfterStoreFrontProductsAssertions"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPageAfterStoreFrontProductsAssertions"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree('$$createNewRootCategoryA.name$$')}}" stepKey="clickOnNewRootCategoryA"/> <waitForPageLoad stepKey="waitForPageNewRootCategoryALoad" /> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="Default Category" stepKey="enterCategoryNameAsDefaultCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml index 151046f0474e0..5c3f79694e79a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CAdminTest.xml @@ -202,8 +202,7 @@ <!--Admin creates category--> <comment userInput="Admin creates category." stepKey="adminCreatesCategoryComment" before="navigateToCategoryPage"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad time="30" stepKey="waitForCategoryPageLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage"/> <!--Create category under Default Category--> <click selector="{{AdminCategorySidebarTreeSection.categoryTreeRoot}}" stepKey="clickDefaultCategory"/> <actionGroup ref="CheckCategoryNameIsRequiredFieldActionGroup" stepKey="checkCategoryNameIsRequired"/> @@ -218,8 +217,7 @@ <!--Admin moves category--> <comment userInput="Admin moves category." stepKey="adminMovesCategoryComment" before="onCategoryPageToMoveCategory"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="onCategoryPageToMoveCategory"/> - <waitForPageLoad time="30" stepKey="waitForPageLoadMoveCategory"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="onCategoryPageToMoveCategory"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandTree"/> <dragAndDrop selector1="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" selector2="{{AdminCategorySidebarTreeSection.categoryTreeRoot}}" @@ -233,8 +231,7 @@ <!--Admin deletes category--> <comment userInput="Admin deletes category" stepKey="deleteCategoryComment"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="onCategoryPageToDeleteCategory"/> - <waitForPageLoad time="30" stepKey="waitForCategoryPageDelete"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="onCategoryPageToDeleteCategory"/> <actionGroup ref="DeleteCategoryActionGroup" stepKey="deleteCategory"> <argument name="categoryEntity" value="_defaultCategory"/> </actionGroup> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserMysqlTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserMysqlTest.xml index f334a6c5a66ce..6630557b37bd0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserMysqlTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserMysqlTest.xml @@ -59,8 +59,8 @@ <!-- Step 1: User browses catalog --> <comment userInput="Start of browsing catalog" stepKey="startOfBrowsingCatalog"/> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomePage"/> - <waitForElementVisible selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeWaitForWelcomeMessage"/> - <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome"/> + <waitForElementVisible selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="homeWaitForWelcomeMessage"/> + <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="homeCheckWelcome"/> <!-- Open Category --> <comment userInput="Open category" stepKey="commentOpenCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserTest.xml index 94b0deaf6ce1c..441c9cd5eab8b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest/EndToEndB2CGuestUserTest.xml @@ -62,8 +62,8 @@ <!-- Step 1: User browses catalog --> <comment userInput="Start of browsing catalog" stepKey="startOfBrowsingCatalog"/> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomePage"/> - <waitForElementVisible selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeWaitForWelcomeMessage"/> - <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome"/> + <waitForElementVisible selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="homeWaitForWelcomeMessage"/> + <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="homeCheckWelcome"/> <!-- Open Category --> <comment userInput="Open category" stepKey="commentOpenCategory"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml index 4eb5b843eeb35..fbb6893e92b1e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml @@ -49,8 +49,8 @@ <comment userInput="Start of browsing catalog" stepKey="startOfBrowsingCatalog" after="endOfSigningUpUserAccount"/> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnHomePage" after="startOfBrowsingCatalog"/> <waitForPageLoad stepKey="homeWaitForPageLoad" after="amOnHomePage"/> - <waitForElementVisible selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeWaitForWelcomeMessage" after="homeWaitForPageLoad"/> - <see userInput="Welcome, John Doe!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome" after="homeWaitForWelcomeMessage"/> + <waitForElementVisible selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="homeWaitForWelcomeMessage" after="homeWaitForPageLoad"/> + <see userInput="Welcome, John Doe!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="homeCheckWelcome" after="homeWaitForWelcomeMessage"/> <!-- Open Category --> <comment userInput="Open category" stepKey="commentOpenCategory" after="homeCheckWelcome"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml index ea9a4cb08bb08..9b5fa25085e1a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml @@ -40,15 +40,14 @@ <amOnPage url="$$createCategory.name$$.html" stepKey="goToCategoryStorefront2"/> <waitForPageLoad stepKey="waitForCategoryStorefront"/> <dontSeeElement selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct.name$$)}}" stepKey="dontSeeCreatedProduct"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="onCategoryIndexPage"/> - <waitForPageLoad stepKey="waitForCategoryPageLoadAddProducts"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="onCategoryIndexPage"/> <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandAll"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree($$simpleSubCategory.name$$)}}" stepKey="clickOnCreatedSimpleSubCategoryBeforeDelete"/> <waitForPageLoad stepKey="AdminCategoryEditPageLoad"/> <click selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}" stepKey="EnableCategory"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryWithProducts"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see userInput="You saved the category." stepKey="seeSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="seeSuccessMessage"/> <!--Run re-index task--> <magentoCLI command="indexer:reindex" stepKey="reindex"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml index ea7912613f7f2..e109dcb0deea5 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontProductsDisplayUsingElasticSearchTest.xml @@ -113,7 +113,7 @@ <requiredEntity createDataKey="createCategory1"/> </createData> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> <magentoCLI command="indexer:reindex" arguments="catalogsearch_fulltext" stepKey="performReindex"/> <magentoCLI command="cache:clean" arguments="full_page" stepKey="cleanFullPageCache"/> </before> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyComparedAtWebsiteLevelTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyComparedAtWebsiteLevelTest.xml new file mode 100644 index 0000000000000..51150a4ecffb3 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyComparedAtWebsiteLevelTest.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StoreFrontRecentlyComparedAtWebsiteLevelTest"> + <annotations> + <stories value="Recently Compared Product"/> + <title value="Recently Compared Product at website level"/> + <description value="Recently Compared Products widget appears on a page immediately after adding product to compare"/> + <useCaseId value="MC-32763"/> + <testCaseId value="MC-33099"/> + <severity value="MAJOR"/> + <group value="catalog"/> + <group value="widget"/> + </annotations> + <before> + <!--Create Simple Products and Category --> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createSimpleProductToCompareFirst"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="SimpleProduct" stepKey="createSimpleProductToCompareSecond"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="SimpleProduct" stepKey="createSimpleProductNotVisibleFirst"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="SimpleProduct" stepKey="createSimpleProductNotVisibleSecond"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <!-- Login as admin --> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <!-- Create product widget --> + <actionGroup ref="AdminCreateRecentlyProductsWidgetActionGroup" stepKey="createRecentlyComparedProductsWidget"> + <argument name="widget" value="RecentlyComparedProductsWidget"/> + </actionGroup> + <!-- Set Stores > Configurations > Catalog > Recently Viewed/Compared Products > Show for Current = Website --> + <magentoCLI command="config:set {{RecentlyViewedProductScopeWebsite.path}} {{RecentlyViewedProductScopeWebsite.value}}" stepKey="RecentlyViewedProductScopeWebsiteGroup"/> + </before> + <after> + <!-- Customer Logout --> + <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutFromCustomer"/> + <!-- Delete product widget --> + <actionGroup ref="AdminDeleteWidgetActionGroup" stepKey="deleteRecentlyComparedProductsWidget"> + <argument name="widget" value="RecentlyComparedProductsWidget"/> + </actionGroup> + <!-- Logout Admin --> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + <!-- Reset Stores > Configurations > Catalog > Recently Viewed/Compared Products > Show for Current = Website--> + <magentoCLI command="config:set {{RecentlyViewedProductScopeWebsite.path}} {{RecentlyViewedProductScopeWebsite.value}}" stepKey="RecentlyViewedProductScopeWebsite"/> + <!-- Delete Products and Category --> + <deleteData createDataKey="createSimpleProductToCompareFirst" stepKey="deleteSimpleProductToCompareFirst"/> + <deleteData createDataKey="createSimpleProductToCompareSecond" stepKey="deleteSimpleProductToCompareSecond"/> + <deleteData createDataKey="createSimpleProductNotVisibleFirst" stepKey="deleteSimpleProductNotVisibleFirst"/> + <deleteData createDataKey="createSimpleProductNotVisibleSecond" stepKey="deleteSimpleProductNotVisibleSecond"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + </after> + <!--Login to storefront from customer--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="checkWelcomeMessage"/> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.custom_attributes[url_key]$$)}}" stepKey="openCategoryPageAfterAddedProductToCart"/> + <!--Add to compare Simple Product and Simple Product 2--> + <actionGroup ref="StorefrontAddCategoryProductToCompareActionGroup" stepKey="addSimpleProduct1ToCompare" > + <argument name="productVar" value="$$createSimpleProductToCompareFirst$$"/> + </actionGroup> + <actionGroup ref="StorefrontAddCategoryProductToCompareActionGroup" stepKey="addSimpleProduct2ToCompare" > + <argument name="productVar" value="$$createSimpleProductToCompareSecond$$"/> + </actionGroup> + <!--The Compare Products widget displays Simple Product 1 and Simple Product 2--> + <actionGroup ref="StorefrontCheckCompareSidebarProductActionGroup" stepKey="checkSimpleProduct1InCompareSidebar"> + <argument name="productVar" value="$$createSimpleProductToCompareFirst$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCompareSidebarProductActionGroup" stepKey="checkSimpleProduct2InCompareSidebar"> + <argument name="productVar" value="$$createSimpleProductToCompareSecond$$"/> + </actionGroup> + + <!--Click Clear all in the Compare Products widget--> + <actionGroup ref="StorefrontClearCompareActionGroup" stepKey="clearCompareList"/> + <!--The Recently Compared widget displays Simple Product 1 and Simple Product 2--> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.custom_attributes[url_key]$$)}}" stepKey="openCategoryPageToCheckProductsInRecentlyComparedSidebar"/> + <actionGroup ref="StorefrontAssertProductInRecentlyComparedWidgetActionGroup" stepKey="checkSimpleProduct1ExistInRecentlyComparedWidget"> + <argument name="product" value="$$createSimpleProductToCompareFirst$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertProductInRecentlyComparedWidgetActionGroup" stepKey="checkSimpleProduct2ExistInRecentlyComparedWidget"> + <argument name="product" value="$$createSimpleProductToCompareSecond$$"/> + </actionGroup> + <!--The Recently Compared widget not displays Simple Product 3 and Simple Product 4--> + <actionGroup ref="StorefrontAssertNotExistProductInRecentlyComparedWidgetActionGroup" stepKey="checkSimpleProduct3NotExistInRecentlyComparedWidget"> + <argument name="product" value="$$createSimpleProductNotVisibleFirst$$"/> + </actionGroup> + <actionGroup ref="StorefrontAssertNotExistProductInRecentlyComparedWidgetActionGroup" stepKey="checkSimpleProduct4NotExistInRecentlyComparedWidget"> + <argument name="product" value="$$createSimpleProductNotVisibleSecond$$"/> + </actionGroup> + <amOnPage url="customer/account/logout/" stepKey="logoutCustomer"/> + <waitForPageLoad time="30" stepKey="waitForPageLoad2"/> + </test> +</tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml index 284b2f6eeb16a..6d4a848f414fa 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StoreFrontRecentlyViewedAtStoreViewLevelTest.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ --> <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="StoreFrontRecentlyViewedAtStoreViewLevelTest"> <annotations> <stories value="Recently Viewed Product"/> @@ -19,7 +19,7 @@ </annotations> <before> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <!--Create Simple Product and Category --> + <!--Create Simple Product and Category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> <createData entity="SimpleProduct" stepKey="createSimpleProduct1"> <requiredEntity createDataKey="createCategory"/> @@ -37,6 +37,8 @@ <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreViewOne"> <argument name="customStore" value="customStoreEN"/> </actionGroup> + <magentoCron stepKey="runCronIndex" groups="index"/> + <!-- Set Stores > Configurations > Catalog > Recently Viewed/Compared Products > Show for Current = store view--> <magentoCLI command="config:set {{RecentlyViewedProductScopeStore.path}} {{RecentlyViewedProductScopeStore.value}}" stepKey="RecentlyViewedProductScopeStore"/> </before> @@ -66,28 +68,26 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <magentoCLI command="indexer:reindex" stepKey="reindex"/> <magentoCLI command="cache:flush" stepKey="flushCacheAfterDeletion"/> - </after> - <!--Create widget for recently viewed products--> + <!--Create widget for recently viewed products--> <actionGroup ref="AdminEditCMSPageContentActionGroup" stepKey="clearRecentlyViewedWidgetsFromCMSContentBefore"> - <argument name="content" value="{{CmsHomePageContent.content}}"/> - <argument name="pageId" value="{{CmsHomePageContent.page_id}}"/> + <argument name="content" value="{{CmsHomePageContent.content}}"/> + <argument name="pageId" value="{{CmsHomePageContent.page_id}}"/> </actionGroup> <amOnPage url="{{AdminCmsPageEditPage.url(CmsHomePageContent.page_id)}}" stepKey="navigateToEditHomePagePage"/> <waitForPageLoad time="50" stepKey="waitForContentPageToLoad"/> <actionGroup ref="AdminInsertRecentlyViewedWidgetActionGroup" stepKey="insertRecentlyViewedWidget"> - <argument name="attributeSelector1" value="show_attributes"/> - <argument name="attributeSelector2" value="show_buttons"/> - <argument name="productAttributeSection1" value="1"/> - <argument name="productAttributeSection2" value="4"/> - <argument name="buttonToShowSection1" value="1"/> - <argument name="buttonToShowSection2" value="3"/> + <argument name="attributeSelector1" value="show_attributes"/> + <argument name="attributeSelector2" value="show_buttons"/> + <argument name="productAttributeSection1" value="1"/> + <argument name="productAttributeSection2" value="4"/> + <argument name="buttonToShowSection1" value="1"/> + <argument name="buttonToShowSection2" value="3"/> </actionGroup> - <!-- Warm up cache --> <magentoCLI command="cache:flush" stepKey="flushCacheAfterWidgetCreated"/> <!-- Navigate to product 3 on store front --> @@ -95,7 +95,7 @@ <amOnPage url="{{StorefrontProductPage.url($createSimpleProduct3.name$)}}" stepKey="goToStore1ProductPage3"/> <!-- Go to Home Page --> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="amOnHomePage"/> - <actionGroup ref="AssertSeeProductDetailsOnStorefrontRecentlyViewedWidgetActionGroup" stepKey="assertStore1RecentlyViewedProduct2"> + <actionGroup ref="AssertSeeProductDetailsOnStorefrontRecentlyViewedWidgetActionGroup" stepKey="assertStore1RecentlyViewedProduct2"> <argument name="productName" value="$$createSimpleProduct2.name$$"/> <argument name="productPosition" value="2"/> </actionGroup> @@ -104,7 +104,7 @@ <argument name="productPosition" value="1"/> </actionGroup> - <!-- Switch store view --> + <!-- Switch store view --> <waitForPageLoad time="40" stepKey="waitForStorefrontPageLoad"/> <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="switchStoreViewActionGroup"> <argument name="storeView" value="customStoreEN"/> @@ -126,9 +126,9 @@ </actionGroup> <grabTextFrom selector="{{StoreFrontRecentlyViewedProductSection.ProductName('2')}}" stepKey="grabDontSeeHomeProduct3"/> - <assertNotContains stepKey="assertNotSeeProduct3"> - <actualResult type="const">$grabDontSeeHomeProduct3</actualResult> - <expectedResult type="const">$$createSimpleProduct3.name$$</expectedResult> + <assertNotContains stepKey="assertNotSeeProduct3"> + <actualResult type="const">$grabDontSeeHomeProduct3</actualResult> + <expectedResult type="const">$$createSimpleProduct3.name$$</expectedResult> </assertNotContains> <actionGroup ref="StorefrontSwitchDefaultStoreViewActionGroup" stepKey="switchToDefualtStoreView"/> @@ -145,8 +145,8 @@ <grabTextFrom selector="{{StoreFrontRecentlyViewedProductSection.ProductName('2')}}" stepKey="grabDontSeeHomeProduct1"/> <assertNotContains stepKey="assertNotSeeProduct1"> - <actualResult type="const">$grabDontSeeHomeProduct1</actualResult> - <expectedResult type="const">$$createSimpleProduct1.name$$</expectedResult> + <actualResult type="const">$grabDontSeeHomeProduct1</actualResult> + <expectedResult type="const">$$createSimpleProduct1.name$$</expectedResult> </assertNotContains> </test> </tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontConfigurableOptionsThumbImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontConfigurableOptionsThumbImagesTest.xml index c22f91b5394ea..dec36d72a50d6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontConfigurableOptionsThumbImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontConfigurableOptionsThumbImagesTest.xml @@ -165,7 +165,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> </after> <!-- Open ConfigProduct in Store Front Page --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontEnsureThatAccordionAnchorIsVisibleOnViewportOnceClickedTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontEnsureThatAccordionAnchorIsVisibleOnViewportOnceClickedTest.xml index 8acc6272d5da4..020c3d85b9fdf 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontEnsureThatAccordionAnchorIsVisibleOnViewportOnceClickedTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontEnsureThatAccordionAnchorIsVisibleOnViewportOnceClickedTest.xml @@ -90,8 +90,14 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveSimpleProduct"/> <!-- Go to frontend and make a user account and login with it --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="signUpNewUser"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <!-- Go to the product view page --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml index 95af6e299662b..767e0c88b7af2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductCustomOptionsDifferentStoreViewsTest.xml @@ -199,8 +199,8 @@ <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="openOrdersGrid"> <argument name="orderId" value="{$grabOrderNumber}"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad10"/> + + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <!-- Checking the correctness of displayed custom options for user parameters on Order --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitleTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitleTest.xml index 3c1dc2bc844cf..fbecc15a59b1f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitleTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontPurchaseProductWithCustomOptionsWithLongValuesTitleTest.xml @@ -104,8 +104,8 @@ <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <!-- Checking the correctness of displayed custom options for user parameters on Order --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml index 66d811ced9ac6..54a9e5a244427 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/VerifyChildCategoriesShouldNotIncludeInMenuTest.xml @@ -19,8 +19,8 @@ <group value="category"/> </annotations> <after> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage2"/> - <waitForPageLoad stepKey="waitForPageLoad3"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage2"/> + <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="clickOnCreatedSimpleSubCategoryBeforeDelete"/> <actionGroup ref="DeleteCategoryActionGroup" stepKey="deleteCategory"> <argument name="categoryEntity" value="SimpleSubCategory"/> @@ -28,8 +28,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage1"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage1"/> <scrollToTopOfPage stepKey="scrollToTopOfPage"/> <!--Create new category under Default Category--> <actionGroup ref="CreateCategoryActionGroup" stepKey="createSubcategory1"> @@ -44,8 +43,7 @@ <seeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SimpleSubCategory.name)}}" stepKey="seeSimpleSubCategoryOnStorefront1"/> <dontSeeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SubCategoryWithParent.name)}}" stepKey="dontSeeSubCategoryWithParentOnStorefront1"/> <!--Set Include in menu to No on created category under Default Category --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage2"/> - <waitForPageLoad stepKey="waitForPageLoad3"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage2"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="clickOnCreatedSimpleSubCategory1"/> <click selector="{{AdminCategoryBasicFieldSection.includeInMenuLabel}}" stepKey="setNoToIncludeInMenuSelect"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton1"/> @@ -56,8 +54,7 @@ <dontSeeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SimpleSubCategory.name)}}" stepKey="dontSeeSimpleSubCategoryOnStorefront1"/> <dontSeeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SubCategoryWithParent.name)}}" stepKey="dontSeeSubCategoryWithParentOnStorefront2"/> <!--Set Enable category to No and Include in menu to Yes on created category under Default Category --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage3"/> - <waitForPageLoad stepKey="waitForPageLoad5"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage3"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="clickOnCreatedSimpleSubCategory2"/> <click selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}" stepKey="SetNoToEnableCategorySelect"/> <click selector="{{AdminCategoryBasicFieldSection.includeInMenuLabel}}" stepKey="SetYesToIncludeInMenuSelect"/> @@ -69,8 +66,7 @@ <dontSeeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SimpleSubCategory.name)}}" stepKey="dontSeeSimpleSubCategoryOnStorefront2"/> <dontSeeElement selector="{{StorefrontHeaderSection.NavigationCategoryByName(SubCategoryWithParent.name)}}" stepKey="dontSeeSubCategoryWithParentOnStorefront3"/> <!--Set Enable category to No and Include in menu to No on created category under Default Category --> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage4"/> - <waitForPageLoad stepKey="waitForPageLoad7"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage4"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree(SimpleSubCategory.name)}}" stepKey="clickOnCreatedSimpleSubCategory3"/> <click selector="{{AdminCategoryBasicFieldSection.includeInMenuLabel}}" stepKey="setNoToIncludeInMenuSelect2"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="clickSaveButton3"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml index b439223674b60..a15081e0cbda3 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/VerifyTinyMCEv4IsNativeWYSIWYGOnCatalogTest.xml @@ -23,8 +23,7 @@ <actionGroup ref="EnabledWYSIWYGActionGroup" stepKey="enableWYSIWYG"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> </before> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToNewCatalog"/> - <waitForPageLoad stepKey="wait1"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToNewCatalog"/> <waitForLoadingMaskToDisappear stepKey="wait2" /> <click selector="{{AdminCategorySidebarActionSection.AddSubcategoryButton}}" stepKey="clickOnAddSubCategory"/> <fillField selector="{{AdminCategoryBasicFieldSection.CategoryNameInput}}" userInput="{{SimpleSubCategory.name}}" stepKey="enterCategoryName"/> diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Layer/FilterListTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Layer/FilterListTest.php index 84c433379b156..8fdd41281d807 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Layer/FilterListTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Layer/FilterListTest.php @@ -94,13 +94,9 @@ public function testGetFilters($method, $value, $expectedClass) $this->objectManagerMock->expects($this->at(1)) ->method('create') - ->with( - $expectedClass, - [ - 'data' => ['attribute_model' => $this->attributeMock], - 'layer' => $this->layerMock - ] - ) + ->with($expectedClass, [ + 'data' => ['attribute_model' => $this->attributeMock], + 'layer' => $this->layerMock]) ->will($this->returnValue('filter')); $this->attributeMock->expects($this->once()) @@ -169,8 +165,8 @@ public function getFiltersDataProvider() { return [ [ - 'method' => 'getFrontendInput', - 'value' => 'price', + 'method' => 'getAttributeCode', + 'value' => FilterList::PRICE_FILTER, 'expectedClass' => 'PriceFilterClass', ], [ @@ -179,8 +175,8 @@ public function getFiltersDataProvider() 'expectedClass' => 'DecimalFilterClass', ], [ - 'method' => 'getFrontendInput', - 'value' => 'text', + 'method' => 'getAttributeCode', + 'value' => null, 'expectedClass' => 'AttributeFilterClass', ] ]; @@ -195,8 +191,8 @@ public function getFiltersWithoutCategoryDataProvider(): array { return [ 'Filters contains only price attribute' => [ - 'method' => 'getFrontendInput', - 'value' => 'price', + 'method' => 'getAttributeCode', + 'value' => FilterList::PRICE_FILTER, 'expectedClass' => 'PriceFilterClass', 'expectedResult' => [ 'filter' diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Layout/DepersonalizePluginTest.php index d644443e461a2..89c588b5e32a2 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -3,59 +3,82 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Catalog\Test\Unit\Model\Layout; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Catalog\Model\Layout\DepersonalizePlugin; +use Magento\Catalog\Model\Session as CatalogSession; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\LayoutInterface; +use Magento\PageCache\Model\DepersonalizeChecker; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class DepersonalizePluginTest extends \PHPUnit\Framework\TestCase +/** + * Unit tests for \Magento\Catalog\Model\Layout\DepersonalizePlugin class. + */ +class DepersonalizePluginTest extends TestCase { /** - * @var \Magento\Catalog\Model\Layout\DepersonalizePlugin + * @var DepersonalizePlugin */ - protected $plugin; + private $plugin; /** - * @var \Magento\Catalog\Model\Session|\PHPUnit_Framework_MockObject_MockObject + * @var CatalogSession|MockObject */ - protected $catalogSessionMock; + private $catalogSessionMock; /** - * @var \Magento\PageCache\Model\DepersonalizeChecker|\PHPUnit_Framework_MockObject_MockObject + * @var DepersonalizeChecker|MockObject */ - protected $depersonalizeCheckerMock; + private $depersonalizeCheckerMock; /** - * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject + * @var LayoutInterface|MockObject */ - protected $resultLayout; + private $layoutMock; + /** + * @inheritdoc + */ protected function setUp() { - $this->layoutMock = $this->createMock(\Magento\Framework\View\Layout::class); - $this->catalogSessionMock = $this->createPartialMock(\Magento\Catalog\Model\Session::class, ['clearStorage']); - $this->resultLayout = $this->createMock(\Magento\Framework\View\Layout::class); - $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); - - $this->plugin = (new ObjectManager($this))->getObject( - \Magento\Catalog\Model\Layout\DepersonalizePlugin::class, - ['catalogSession' => $this->catalogSessionMock, 'depersonalizeChecker' => $this->depersonalizeCheckerMock] + $this->layoutMock = $this->getMockForAbstractClass(LayoutInterface::class); + $this->catalogSessionMock = $this->createPartialMock(CatalogSession::class, ['clearStorage']); + $this->depersonalizeCheckerMock = $this->createMock(DepersonalizeChecker::class); + + $this->plugin = (new ObjectManagerHelper($this))->getObject( + DepersonalizePlugin::class, + [ + 'catalogSession' => $this->catalogSessionMock, + 'depersonalizeChecker' => $this->depersonalizeCheckerMock, + ] ); } - public function testAfterGenerateXml() + /** + * Test afterGenerateElements method when depersonalization is needed. + * + * @return void + */ + public function testAfterGenerateElements(): void { $this->catalogSessionMock->expects($this->once())->method('clearStorage'); $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $this->resultLayout); - $this->assertEquals($this->resultLayout, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } - public function testAfterGenerateXmlNoDepersonalize() + /** + * Test afterGenerateElements method when depersonalization is not needed. + * + * @return void + */ + public function testAfterGenerateElementsNoDepersonalize(): void { $this->catalogSessionMock->expects($this->never())->method('clearStorage'); $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $this->resultLayout); - $this->assertEquals($this->resultLayout, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php index 91441890e83b1..c58a652fb5c1e 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php @@ -6,7 +6,7 @@ namespace Magento\Catalog\Test\Unit\Model\Product; -use Magento\Catalog\Api\Data\ProductExtension; +use Magento\Catalog\Api\Data\ProductExtensionInterface; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Attribute\ScopeOverriddenValue; use Magento\Catalog\Model\Product; @@ -106,9 +106,9 @@ protected function setUp() public function testCopy(): void { $stockItem = $this->createMock(StockItemInterface::class); - $extensionAttributes = $this->getMockBuilder(ProductExtension::class) + $extensionAttributes = $this->getMockBuilder(ProductExtensionInterface::class) ->setMethods(['getStockItem', 'setData']) - ->getMock(); + ->getMockForAbstractClass(); $extensionAttributes ->expects($this->once()) ->method('getStockItem') @@ -262,9 +262,9 @@ public function testUrlAlreadyExistsExceptionWhileCopyStoresUrl(): void { $stockItem = $this->getMockBuilder(StockItemInterface::class) ->getMock(); - $extensionAttributes = $this->getMockBuilder(ProductExtension::class) + $extensionAttributes = $this->getMockBuilder(ProductExtensionInterface::class) ->setMethods(['getStockItem', 'setData']) - ->getMock(); + ->getMockForAbstractClass(); $extensionAttributes ->expects($this->once()) ->method('getStockItem') diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/ReadHandlerTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/ReadHandlerTest.php index 2e93aa79aefd2..b2ee8180cd8b5 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/ReadHandlerTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/ReadHandlerTest.php @@ -6,32 +6,33 @@ namespace Magento\Catalog\Test\Unit\Model\Product\Website; -use Magento\Catalog\Api\Data\ProductExtension; +use Magento\Catalog\Api\Data\ProductExtensionInterface; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Website\ReadHandler; use Magento\Catalog\Model\ResourceModel\Product as ResourceModel; +use PHPUnit\Framework\MockObject\MockObject; class ReadHandlerTest extends \PHPUnit\Framework\TestCase { - /** @var ResourceModel\Website\Link | \PHPUnit_Framework_MockObject_MockObject */ - private $websiteLink; + /** @var ResourceModel\Website\Link|MockObject */ + private $websiteLinkMock; - /** @var \PHPUnit_Framework_MockObject_MockObject */ - private $extensionAttributes; + /** @var MockObject */ + private $extensionAttributesMock; /** @var ReadHandler */ private $readHandler; public function setUp() { - $this->websiteLink = $this->getMockBuilder(ResourceModel\Website\Link::class) + $this->websiteLinkMock = $this->getMockBuilder(ResourceModel\Website\Link::class) ->disableOriginalConstructor() ->getMock(); - $this->extensionAttributes = $this->getMockBuilder(ProductExtension::class) + $this->extensionAttributesMock = $this->getMockBuilder(ProductExtensionInterface::class) ->setMethods(['setWebsiteIds', 'getWebsiteIds']) ->disableArgumentCloning() - ->getMock(); - $this->readHandler = new ReadHandler($this->websiteLink); + ->getMockForAbstractClass(); + $this->readHandler = new ReadHandler($this->websiteLinkMock); } public function testExecuteWithNonCachedExtensionAttributes() @@ -44,20 +45,20 @@ public function testExecuteWithNonCachedExtensionAttributes() ->method('getId') ->willReturn($productId); $websiteIds = [1,2]; - $this->websiteLink->expects($this->once()) + $this->websiteLinkMock->expects($this->once()) ->method("getWebsiteIdsByProductId") ->with($productId) ->willReturn($websiteIds); $product->expects($this->exactly(2)) ->method('getExtensionAttributes') - ->willReturn($this->extensionAttributes); - $this->extensionAttributes->expects($this->once()) + ->willReturn($this->extensionAttributesMock); + $this->extensionAttributesMock->expects($this->once()) ->method("getWebsiteIds") ->willReturn(null); $product->expects($this->once()) ->method('setExtensionAttributes') - ->with($this->extensionAttributes); + ->with($this->extensionAttributesMock); $this->assertEquals($this->readHandler->execute($product, []), $product); } @@ -68,15 +69,15 @@ public function testExecuteWithCachedWebsiteIds() ->disableOriginalConstructor() ->getMock(); $websiteIds = [1,2]; - $this->extensionAttributes->expects($this->once()) + $this->extensionAttributesMock->expects($this->once()) ->method("getWebsiteIds") ->willReturn($websiteIds); $product->expects($this->never()) ->method('setExtensionAttributes') - ->with($this->extensionAttributes); + ->with($this->extensionAttributesMock); $product->expects($this->once()) ->method('getExtensionAttributes') - ->willReturn($this->extensionAttributes); + ->willReturn($this->extensionAttributesMock); $this->assertEquals($this->readHandler->execute($product, []), $product); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/SaveHandlerTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/SaveHandlerTest.php index b2c9a182648ca..392f01a62b3ee 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/SaveHandlerTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Website/SaveHandlerTest.php @@ -6,7 +6,7 @@ namespace Magento\Catalog\Test\Unit\Model\Product\Website; -use Magento\Catalog\Api\Data\ProductExtension; +use Magento\Catalog\Api\Data\ProductExtensionInterface; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\ResourceModel\Product\Website\Link; use Magento\Catalog\Model\Product\Website\SaveHandler; @@ -15,19 +15,20 @@ use Magento\Framework\Api\ExtensionAttributesInterface; use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; class SaveHandlerTest extends \PHPUnit\Framework\TestCase { - /** @var ResourceModel\Website\Link | \PHPUnit_Framework_MockObject_MockObject */ + /** @var ResourceModel\Website\Link|MockObject */ private $productWebsiteLink; - /** @var StoreManagerInterface | \PHPUnit_Framework_MockObject_MockObject */ + /** @var StoreManagerInterface|MockObject */ private $storeManager; /** @var SaveHandler */ private $saveHandler; - /** @var ProductInterface | \PHPUnit_Framework_MockObject_MockObject */ + /** @var ProductInterface|MockObject */ private $product; public function setUp() diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index 0dc294e139d3e..1f3faf659e390 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -42,12 +42,10 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use PHPUnit_Framework_MockObject_MockObject as MockObject; /** - * Class ProductRepositoryTest - * @package Magento\Catalog\Test\Unit\Model * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php index b3acaa4b8bbed..ba81d42e75c76 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php @@ -129,7 +129,6 @@ public function testCreateWithNotFilterableInGridAttribute(array $filterModifier 'visible' => null, 'filter' => $filter, 'component' => 'Magento_Ui/js/grid/columns/column', - '__disableTmpl' => ['label' => true] ], ], 'context' => $this->context, @@ -206,7 +205,6 @@ public function testCreateDateColumn( 'component' => 'Magento_Ui/js/grid/columns/date', 'timezone' => $expectedTimezone, 'dateFormat' => $expectedDateFormat, - '__disableTmpl' => ['label' => true], 'options' => [ 'showsTime' => $showsTime ] diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php index c704d9f89581d..f34ebd2e1cf4d 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php @@ -11,14 +11,15 @@ use Magento\Framework\AuthorizationInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Element\UiComponent\ContextInterface; +use PHPUnit\Framework\MockObject\MockObject; /** - * MassAction test + * MassAction test for Component Product */ class MassActionTest extends \PHPUnit\Framework\TestCase { /** - * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ContextInterface|MockObject */ private $contextMock; @@ -28,7 +29,7 @@ class MassActionTest extends \PHPUnit\Framework\TestCase private $objectManager; /** - * @var AuthorizationInterface|\PHPUnit_Framework_MockObject_MockObject + * @var AuthorizationInterface|MockObject */ private $authorizationMock; @@ -107,7 +108,6 @@ public function getPrepareDataProvider() : array 'type' => 'first_action', 'label' => 'First Action', 'url' => '/module/controller/firstAction', - '__disableTmpl' => true ], ], [ @@ -127,7 +127,6 @@ public function getPrepareDataProvider() : array 'url' => '/module/controller/secondSubAction2' ], ], - '__disableTmpl' => true ], ], [ @@ -147,7 +146,6 @@ public function getPrepareDataProvider() : array 'url' => '/module/controller/disable' ], ], - '__disableTmpl' => true ], ], [ @@ -167,7 +165,6 @@ public function getPrepareDataProvider() : array 'url' => '/module/controller/disable' ], ], - '__disableTmpl' => true ], false, false @@ -178,7 +175,6 @@ public function getPrepareDataProvider() : array 'type' => 'delete', 'label' => 'First Action', 'url' => '/module/controller/delete', - '__disableTmpl' => true ], ], [ @@ -187,7 +183,6 @@ public function getPrepareDataProvider() : array 'type' => 'delete', 'label' => 'First Action', 'url' => '/module/controller/delete', - '__disableTmpl' => true ], false, false @@ -198,7 +193,6 @@ public function getPrepareDataProvider() : array 'type' => 'delete', 'label' => 'First Action', 'url' => '/module/controller/attributes', - '__disableTmpl' => true ], ], [ @@ -207,7 +201,6 @@ public function getPrepareDataProvider() : array 'type' => 'delete', 'label' => 'First Action', 'url' => '/module/controller/attributes', - '__disableTmpl' => true ], false, false diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index 91e22407acc43..917ef2bd522f8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -570,7 +570,6 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_not_new_locked_and_required' => [ @@ -590,7 +589,6 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => ['label' => true, 'code' => true] ], 'locked' => true, ], @@ -611,7 +609,6 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_new_and_not_required' => [ @@ -631,7 +628,6 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_new_locked_and_not_required' => [ @@ -651,7 +647,6 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => ['label' => true, 'code' => true] ], 'locked' => true, ], @@ -672,7 +667,6 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'datetime_null_prod_not_new_and_required' => [ @@ -692,7 +686,6 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => ['label' => true, 'code' => true] ], 'locked' => false, 'frontendInput' => 'datetime', diff --git a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php index b902e741c006c..c7afc61e38ca4 100644 --- a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php +++ b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php @@ -92,7 +92,6 @@ public function create($attribute, $context, array $config = []) 'filter' => ($attribute->getIsFilterableInGrid() || array_key_exists($columnName, $filterModifiers)) ? $this->getFilterType($attribute->getFrontendInput()) : null, - '__disableTmpl' => ['label' => true], ], $config ); diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php index 596b0f4118599..c54cfa28fcda0 100644 --- a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php +++ b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php @@ -11,7 +11,7 @@ use Magento\Framework\UrlInterface; /** - * Class ProductActions + * Class ProductActions for Listing Columns * * @api * @since 100.0.2 @@ -60,7 +60,6 @@ public function prepareDataSource(array $dataSource) ), 'label' => __('Edit'), 'hidden' => false, - '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php index f770f6b9c497f..be6de45e20de2 100644 --- a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php +++ b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php @@ -13,7 +13,7 @@ use Magento\Ui\Component\AbstractComponent; /** - * Class MassAction + * Class MassAction for Component Product */ class MassAction extends AbstractComponent { @@ -53,7 +53,7 @@ public function prepare() : void $actionType = $actionComponent->getConfiguration()['type']; if ($this->isActionAllowed($actionType)) { // phpcs:ignore Magento2.Performance.ForeachArrayMerge - $config['actions'][] = array_merge($actionComponent->getConfiguration(), ['__disableTmpl' => true]); + $config['actions'][] = array_merge($actionComponent->getConfiguration()); } } $origConfig = $this->getConfiguration(); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index f19f5abd0b423..174a01b72a109 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -26,7 +26,7 @@ use Magento\Framework\Stdlib\ArrayManager; /** - * Class AdvancedPricing + * Class for Product Modifier Advanced Pricing * * @api * @@ -559,6 +559,7 @@ private function getTierPriceStructure($tierPricePath) ], 'imports' => [ 'priceValue' => '${ $.provider }:data.product.price', + '__disableTmpl' => ['priceValue' => false], ], ], ], @@ -664,6 +665,7 @@ private function customizeAdvancedPricing() 'actions' => [ [ 'targetName' => '${ $.name }', + '__disableTmpl' => ['targetName' => false], 'actionName' => 'actionDone' ] ] diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php index 53c9595b59e76..cb87e4dc9910f 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php @@ -80,13 +80,6 @@ public function getOptions() $collectionData = $collection->getData() ?? []; - array_walk( - $collectionData, - function (&$attribute) { - $attribute['__disableTmpl'] = true; - } - ); - return $collectionData; } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Attributes.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Attributes.php index a6b9856a4a0ed..5690e4af72375 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Attributes.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Attributes.php @@ -13,7 +13,7 @@ use Magento\Ui\Component\Container; /** - * Class Attributes + * Class for Product Modifier Attributes * * @api * @since 101.0.0 @@ -138,6 +138,7 @@ private function customizeAddAttributeModal(array $meta) 'actions' => [ [ 'targetName' => '${ $.name }', + '__disableTmpl' => ['targetName' => false], 'actionName' => 'actionCancel' ] ] @@ -148,6 +149,7 @@ private function customizeAddAttributeModal(array $meta) 'actions' => [ [ 'targetName' => '${ $.name }.product_attributes_grid', + '__disableTmpl' => ['targetName' => false], 'actionName' => 'save' ], [ @@ -271,6 +273,7 @@ private function customizeCreateAttributeModal(array $meta) 'externalProvider' => 'product_attribute_add_form' . '.product_attribute_add_form_data_source', 'toolbarContainer' => '${ $.parentName }', + '__disableTmpl' => ['toolbarContainer' => false], 'formSubmitType' => 'ajax', 'saveUrl' => $this->urlBuilder->getUrl('catalog/product_attribute/save', $params), 'validateUrl' => $this->urlBuilder->getUrl( @@ -281,11 +284,17 @@ private function customizeCreateAttributeModal(array $meta) 'productType' => $this->locator->getProduct()->getTypeId(), 'imports' => [ 'attributeSetId' => '${ $.provider }:data.product.attribute_set_id', + '__disableTmpl' => ['attributeSetId' => false], ], 'exports' => [ 'saveUrl' => '${ $.externalProvider }:client.urls.save', 'validateUrl' => '${ $.externalProvider }:client.urls.beforeSave', 'attributeSetId' => '${ $.externalProvider }:params.set', + '__disableTmpl' => [ + 'saveUrl' => false, + 'validateUrl' => false, + 'attributeSetId' => false + ], ] ] ] @@ -321,6 +330,7 @@ private function customizeAttributesGrid(array $meta) 'externalFilterMode' => true, 'dataLinks' => ['imports' => false, 'exports' => false], 'formProvider' => 'ns = ${ $.namespace }, index = product_form', + '__disableTmpl' => ['selectionsProvider' => false, 'formProvider' => false], 'groupCode' => static::GROUP_CODE, 'groupName' => static::GROUP_NAME, 'groupSortOrder' => static::GROUP_SORT_ORDER, @@ -330,10 +340,12 @@ private function customizeAttributesGrid(array $meta) 'productType' => $this->locator->getProduct()->getTypeId(), 'loading' => false, 'imports' => [ - 'attributeSetId' => '${ $.provider }:data.product.attribute_set_id' + 'attributeSetId' => '${ $.provider }:data.product.attribute_set_id', + '__disableTmpl' => ['attributeSetId' => false], ], 'exports' => [ - 'attributeSetId' => '${ $.externalProvider }:params.template_id' + 'attributeSetId' => '${ $.externalProvider }:params.template_id', + '__disableTmpl' => ['attributeSetId' => false], ] ], ], diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php index cd1f8e8e3379b..7608173c8edfc 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php @@ -210,6 +210,7 @@ protected function createNewCategoryModal(array $meta) 'ns' => 'new_category_form', 'externalProvider' => 'new_category_form.new_category_form_data_source', 'toolbarContainer' => '${ $.parentName }', + '__disableTmpl' => ['toolbarContainer' => false], 'formSubmitType' => 'ajax', ], ], diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php index 65792b395dc06..2e1ea59573c3b 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php @@ -351,6 +351,7 @@ protected function getHeaderContainerConfig($sortOrder) [ 'targetName' => '${ $.ns }.${ $.ns }.' . static::GROUP_CUSTOM_OPTIONS_NAME . '.' . static::GRID_OPTIONS_NAME, + '__disableTmpl' => ['targetName' => false], 'actionName' => 'processingAddChild', ] ] @@ -388,7 +389,10 @@ protected function getOptionsGridConfig($sortOrder) 'collapsibleHeader' => true, 'sortOrder' => $sortOrder, 'dataProvider' => static::CUSTOM_OPTIONS_LISTING, - 'imports' => ['insertData' => '${ $.provider }:${ $.dataProvider }'], + 'imports' => [ + 'insertData' => '${ $.provider }:${ $.dataProvider }', + '__disableTmpl' => ['insertData' => false], + ], ], ], ], @@ -513,7 +517,8 @@ protected function getImportOptionsModalConfig() 'exports' => true ], 'exports' => [ - 'currentProductId' => '${ $.externalProvider }:params.current_product_id' + 'currentProductId' => '${ $.externalProvider }:params.current_product_id', + '__disableTmpl' => ['currentProductId' => false], ] ], ], @@ -559,7 +564,8 @@ protected function getCommonContainerConfig($sortOrder) 'valueUpdate' => 'input', 'imports' => [ 'optionId' => '${ $.provider }:${ $.parentScope }.option_id', - 'isUseDefault' => '${ $.provider }:${ $.parentScope }.is_use_default' + 'isUseDefault' => '${ $.provider }:${ $.parentScope }.is_use_default', + '__disableTmpl' => ['optionId' => false, 'isUseDefault' => false], ] ], ], @@ -638,7 +644,8 @@ protected function getSelectTypeGridConfig($sortOrder) 'imports' => [ 'optionId' => '${ $.provider }:${ $.parentScope }.option_id', 'optionTypeId' => '${ $.provider }:${ $.parentScope }.option_type_id', - 'isUseDefault' => '${ $.provider }:${ $.parentScope }.is_use_default' + 'isUseDefault' => '${ $.provider }:${ $.parentScope }.is_use_default', + '__disableTmpl' => ['optionId' => false, 'optionTypeId' => false, 'isUseDefault' => false], ], 'service' => [ 'template' => 'Magento_Catalog/form/element/helper/custom-option-type-service', diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index 25e816f79639a..0295e778f2b9b 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -686,7 +686,6 @@ public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupC 'scopeLabel' => $this->getScopeLabel($attribute), 'globalScope' => $this->isScopeGlobal($attribute), 'sortOrder' => $sortOrder * self::SORT_ORDER_MULTIPLIER, - '__disableTmpl' => ['label' => true, 'code' => true] ] ); $product = $this->locator->getProduct(); @@ -861,7 +860,6 @@ public function setupAttributeContainerMeta(ProductAttributeInterface $attribute 'breakLine' => false, 'label' => $attribute->getDefaultFrontendLabel(), 'required' => $attribute->getIsRequired(), - '__disableTmpl' => ['label' => true] ] ); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index ebc0425be0188..371022e70123d 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -228,7 +228,8 @@ protected function customizeWeightField(array $meta) 'addafter' => $this->locator->getStore()->getConfig('general/locale/weight_unit'), 'imports' => $disabled ? [] : [ 'disabled' => '!${$.provider}:' . self::DATA_SCOPE_PRODUCT - . '.product_has_weight:value' + . '.product_has_weight:value', + '__disableTmpl' => ['disabled' => false], ] ] ); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php index b4acb93dcd14f..fb1c310a8a2b4 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php @@ -25,7 +25,7 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status; /** - * Class Related + * Class for Product Modifier Related * * @api * @@ -143,7 +143,8 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc + * * @since 101.0.0 */ public function modifyMeta(array $meta) @@ -182,7 +183,8 @@ public function modifyMeta(array $meta) } /** - * {@inheritdoc} + * @inheritdoc + * * @since 101.0.0 */ public function modifyData(array $data) @@ -528,10 +530,12 @@ protected function getGenericModal(Phrase $title, $scope) 'imports' => [ 'productId' => '${ $.provider }:data.product.current_product_id', 'storeId' => '${ $.provider }:data.product.current_store_id', + '__disableTmpl' => ['productId' => false, 'storeId' => false], ], 'exports' => [ 'productId' => '${ $.externalProvider }:params.current_product_id', 'storeId' => '${ $.externalProvider }:params.current_store_id', + '__disableTmpl' => ['productId' => false, 'storeId' => false], ] ], ], @@ -582,7 +586,8 @@ protected function getGrid($scope) 'thumbnail' => 'thumbnail_src', ], 'links' => [ - 'insertData' => '${ $.provider }:${ $.dataProvider }' + 'insertData' => '${ $.provider }:${ $.dataProvider }', + '__disableTmpl' => ['insertData' => false], ], 'sortOrder' => 2, ], diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php index 9c5fffc5db9b9..c64d3e2e4effb 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/TierPrice.php @@ -138,6 +138,10 @@ private function getUpdatedTierPriceStructure(array $priceMeta) . ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE, ProductPriceOptionsInterface::VALUE_PERCENT => '${ $.parentName }.' . ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PERCENTAGE_VALUE, + '__disableTmpl' => [ + ProductPriceOptionsInterface::VALUE_FIXED => false, + ProductPriceOptionsInterface::VALUE_PERCENT => false, + ], ], ], ], diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Websites.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Websites.php index de204b312a3fd..430b6c004e772 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Websites.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Websites.php @@ -259,7 +259,8 @@ protected function getDynamicRow($websiteId, $sortOrder) 'columnsHeader' => true, 'dndConfig' => ['enabled' => false], 'imports' => [ - 'visible' => '${$.namespace}.${$.namespace}.websites.' . $websiteId . ':checked' + 'visible' => '${$.namespace}.${$.namespace}.websites.' . $websiteId . ':checked', + '__disableTmpl' => ['visible' => false], ], 'itemTemplate' => 'record', 'dataScope' => '', diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/value-type-select.js b/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/value-type-select.js index e1a15a93e793d..ff8a3586d0077 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/value-type-select.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/tier-price/value-type-select.js @@ -19,8 +19,9 @@ define([ * {@inheritdoc} */ initialize: function () { - this._super() - .prepareForm(); + this._super(); + delete this.prices.__disableTmpl; + this.prepareForm(); }, /** diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js index 6589f7eb0ba48..dfc0b4291cd6e 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js @@ -23,6 +23,7 @@ define([ direction: 'product_list_dir', order: 'product_list_order', limit: 'product_list_limit', + page: 'p', modeDefault: 'grid', directionDefault: 'asc', orderDefault: 'position', @@ -81,24 +82,63 @@ define([ }, /** - * @param {String} paramName - * @param {*} paramValue - * @param {*} defaultValue + * @private */ - changeUrl: function (paramName, paramValue, defaultValue) { + getUrlParams: function () { var decode = window.decodeURIComponent, urlPaths = this.options.url.split('?'), - baseUrl = urlPaths[0], urlParams = urlPaths[1] ? urlPaths[1].split('&') : [], - paramData = {}, - parameters, i, form, params, key, input, formKey; + params = {}, + parameters, i; for (i = 0; i < urlParams.length; i++) { parameters = urlParams[i].split('='); - paramData[decode(parameters[0])] = parameters[1] !== undefined ? + params[decode(parameters[0])] = parameters[1] !== undefined ? decode(parameters[1].replace(/\+/g, '%20')) : ''; } + + return params; + }, + + /** + * @returns {String} + * @private + */ + getCurrentLimit: function () { + return this.getUrlParams()[this.options.limit] || this.options.limitDefault; + }, + + /** + * @returns {String} + * @private + */ + getCurrentPage: function () { + return this.getUrlParams()[this.options.page] || 1; + }, + + /** + * @param {String} paramName + * @param {*} paramValue + * @param {*} defaultValue + */ + changeUrl: function (paramName, paramValue, defaultValue) { + var urlPaths = this.options.url.split('?'), + baseUrl = urlPaths[0], + paramData = this.getUrlParams(), + currentPage = this.getCurrentPage(), + form, params, key, input, formKey, newPage; + + if (currentPage > 1 && paramName === this.options.limit) { + newPage = Math.floor(this.getCurrentLimit() * (currentPage - 1) / paramValue) + 1; + + if (newPage > 1) { + paramData[this.options.page] = newPage; + } else { + delete paramData[this.options.page]; + } + } + paramData[paramName] = paramValue; if (this.options.post) { @@ -130,6 +170,7 @@ define([ if (paramValue == defaultValue) { //eslint-disable-line eqeqeq delete paramData[paramName]; } + paramData = $.param(paramData); location.href = baseUrl + (paramData.length ? '?' + paramData : ''); } diff --git a/app/code/Magento/Catalog/view/frontend/web/js/product/provider-compared.js b/app/code/Magento/Catalog/view/frontend/web/js/product/provider-compared.js index 93f01682b4e48..11e092e47ae22 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/product/provider-compared.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/product/provider-compared.js @@ -31,13 +31,27 @@ define([ */ dataFilter: function (data) { var providerData = this.idsStorage.prepareData(customerData.get(this.identifiersConfig.provider)().items), - result = {}; + result = {}, + productCurrentScope, + scopeId; - _.each(data, function (value, key) { - if (!providerData[key]) { - result[key] = value; - } - }); + if (typeof this.data.productCurrentScope !== 'undefined') { + productCurrentScope = this.data.productCurrentScope; + scopeId = productCurrentScope === 'store' ? window.checkout.storeId : + productCurrentScope === 'group' ? window.checkout.storeGroupId : + window.checkout.websiteId; + _.each(data, function (value, key) { + if (!providerData[productCurrentScope + '-' + scopeId + '-' + key]) { + result[key] = value; + } + }); + } else { + _.each(data, function (value, key) { + if (!providerData[key]) { + result[key] = value; + } + }); + } return result; }, diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder.php index f5cf2a9ef82ff..e7ce63784addf 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder.php @@ -8,7 +8,9 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Image; use Magento\Catalog\Model\View\Asset\PlaceholderFactory; +use Magento\Framework\App\Area; use Magento\Framework\View\Asset\Repository as AssetRepository; +use Magento\Framework\View\DesignInterface; /** * Image Placeholder provider @@ -25,16 +27,24 @@ class Placeholder */ private $assetRepository; + /** + * @var DesignInterface + */ + private $themeDesign; + /** * @param PlaceholderFactory $placeholderFactory * @param AssetRepository $assetRepository + * @param DesignInterface $themeDesign */ public function __construct( PlaceholderFactory $placeholderFactory, - AssetRepository $assetRepository + AssetRepository $assetRepository, + DesignInterface $themeDesign ) { $this->placeholderFactory = $placeholderFactory; $this->assetRepository = $assetRepository; + $this->themeDesign = $themeDesign; } /** @@ -52,8 +62,14 @@ public function getPlaceholder(string $imageType): string return $imageAsset->getUrl(); } - return $this->assetRepository->getUrl( - "Magento_Catalog::images/product/placeholder/{$imageType}.jpg" + $params = [ + 'area' => Area::AREA_FRONTEND, + 'themeId' => $this->themeDesign->getConfigurationDesignTheme(Area::AREA_FRONTEND), + ]; + + return $this->assetRepository->getUrlWithParams( + "Magento_Catalog::images/product/placeholder/{$imageType}.jpg", + $params ); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder/Theme.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder/Theme.php deleted file mode 100644 index dc48c5ef69346..0000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Image/Placeholder/Theme.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Image\Placeholder; - -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\View\Design\Theme\ThemeProviderInterface; -use Magento\Store\Model\StoreManagerInterface; - -/** - * Theme provider - */ -class Theme -{ - /** - * @var ScopeConfigInterface - */ - private $scopeConfig; - - /** - * @var StoreManagerInterface - */ - private $storeManager; - - /** - * @var ThemeProviderInterface - */ - private $themeProvider; - - /** - * @param ScopeConfigInterface $scopeConfig - * @param StoreManagerInterface $storeManager - * @param ThemeProviderInterface $themeProvider - */ - public function __construct( - ScopeConfigInterface $scopeConfig, - StoreManagerInterface $storeManager, - ThemeProviderInterface $themeProvider - ) { - $this->scopeConfig = $scopeConfig; - $this->storeManager = $storeManager; - $this->themeProvider = $themeProvider; - } - - /** - * Get theme model - * - * @return array - * @throws \Magento\Framework\Exception\NoSuchEntityException - */ - public function getThemeData(): array - { - $themeId = $this->scopeConfig->getValue( - \Magento\Framework\View\DesignInterface::XML_PATH_THEME_ID, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, - $this->storeManager->getStore()->getId() - ); - - /** @var $theme \Magento\Framework\View\Design\ThemeInterface */ - $theme = $this->themeProvider->getThemeById($themeId); - - $data = $theme->getData(); - $data['themeModel'] = $theme; - - return $data; - } -} diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml index b291fb46ae71c..491f30265906f 100644 --- a/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml +++ b/app/code/Magento/CatalogInventory/Test/Mftf/Test/AssociatedProductToConfigurableOutOfStockTest.xml @@ -103,7 +103,7 @@ <selectOption userInput="$$createConfigProductAttributeOption1.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="configProductFillOption" /> <click stepKey="addSimpleProductToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage"/> <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/> <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> @@ -124,8 +124,7 @@ <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearch"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php b/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php index 38a33b75f552a..64db51132dc36 100644 --- a/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php +++ b/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php @@ -186,7 +186,6 @@ private function prepareMeta() if ($pathField) { $fieldsetPath = $this->arrayManager->slicePath($pathField, 0, -4); - $this->meta = $this->arrayManager->merge( $pathField . '/arguments/data/config', $this->meta, @@ -197,6 +196,7 @@ private function prepareMeta() 'scopeLabel' => '[GLOBAL]', 'imports' => [ 'visible' => '${$.provider}:data.product.stock_data.manage_stock', + '__disableTmpl' => ['visible' => false], ], ] ); @@ -240,6 +240,7 @@ private function prepareMeta() ], 'imports' => [ 'handleChanges' => '${$.provider}:data.product.stock_data.is_qty_decimal', + '__disableTmpl' => ['handleChanges' => false], ], 'sortOrder' => 10, 'disabled' => $this->locator->getProduct()->isLockedAttribute($fieldCode), @@ -269,7 +270,6 @@ private function prepareMeta() 'qty' => $qty, 'advanced_inventory_button' => $advancedInventoryButton, ]; - $this->meta = $this->arrayManager->merge( $fieldsetPath . '/children', $this->meta, diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index d20798aef4838..85961a28fac53 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -11,7 +11,7 @@ <!-- action group to create a new catalog price rule giving a catalogRule entity --> <actionGroup name="NewCatalogPriceRuleByUIActionGroup"> <annotations> - <description>DEPRECATED. Please use set of AG: AdminOpenNewCatalogPriceRuleFormPageActionGroup, AdminCatalogPriceRuleFillMainInfoActionGroup, AdminCatalogPriceRuleFillActionsActionGroup, AdminCatalogPriceRuleSaveAndApplyActionGroup + <description>Consider using set of AG: AdminOpenNewCatalogPriceRuleFormPageActionGroup, AdminCatalogPriceRuleFillMainInfoActionGroup, AdminCatalogPriceRuleFillActionsActionGroup, AdminCatalogPriceRuleSaveAndApplyActionGroup Goes to the Catalog Price Rule grid. Clicks on Add. Fills in the provided Catalog Rule details.</description> </annotations> <arguments> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/NewCatalogPriceRuleByUIWithConditionIsSKUActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/NewCatalogPriceRuleByUIWithConditionIsSKUActionGroup.xml index 217a7519defa7..bd8d1d21bf694 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/NewCatalogPriceRuleByUIWithConditionIsSKUActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/NewCatalogPriceRuleByUIWithConditionIsSKUActionGroup.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="NewCatalogPriceRuleByUIWithConditionIsSKUActionGroup" extends="NewCatalogPriceRuleByUIActionGroup"> <annotations> - <description>DEPRECATED. Please use set of AG: AdminOpenNewCatalogPriceRuleFormPageActionGroup, AdminCatalogPriceRuleFillMainInfoActionGroup, AdminCatalogPriceRuleFillActionsActionGroup, AdminCatalogPriceRuleAddSkuConditionActionGroup, AdminCatalogPriceRuleSaveAndApplyActionGroup + <description>Consider using set of AG: AdminOpenNewCatalogPriceRuleFormPageActionGroup, AdminCatalogPriceRuleFillMainInfoActionGroup, AdminCatalogPriceRuleFillActionsActionGroup, AdminCatalogPriceRuleAddSkuConditionActionGroup, AdminCatalogPriceRuleSaveAndApplyActionGroup EXTENDS: newCatalogPriceRuleByUI. Add a Catalog Price Rule Condition based on the provided SKU.</description> </annotations> <arguments> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml index 8c3d1dad1b2a3..fcae0065f1b53 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml @@ -63,8 +63,7 @@ <!-- Add the product to cart and check that the price is correct there --> <click stepKey="addToCart" selector="{{StorefrontProductActionSection.addToCart}}"/> <waitForPageLoad stepKey="waitForAddedToCart"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForCart"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckout"/> <see stepKey="seeNewPriceInCart" selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$110.70"/> </test> </tests> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleForCustomerGroupTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleForCustomerGroupTest.xml index 65ef23de65380..b9318f72bee9e 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleForCustomerGroupTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleForCustomerGroupTest.xml @@ -56,8 +56,14 @@ <see selector="{{StorefrontCategoryProductSection.ProductInfoByNumber('1')}}" userInput="$110.70" stepKey="seeDiscountedPrice1"/> <!-- Create a user account --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="createAnAccount"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <!-- As a logged in user, go to the storefront category page and should NOT see discount --> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml index 5fb33c9482709..6b34fd1e67e9b 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml @@ -135,8 +135,7 @@ <waitForPageLoad time="30" stepKey="waitForPageLoad4"/> <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <see selector="{{StorefrontMessagesSection.success}}" userInput="You added $$createConfigProduct1.name$ to your shopping cart." stepKey="seeAddToCartSuccessMessage"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniShoppingCart1"/> - <waitForPageLoad time="30" stepKey="waitForPageLoad5"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="openMiniShoppingCart1"/> <see selector="{{StorefrontMinicartSection.productPriceByName($$createConfigProduct1.name$$)}}" userInput="$$createConfigProduct1.price$$" stepKey="seeCorrectProductPrice1"/> </test> </tests> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml index fc37fc893f871..49a9d5e8ae51b 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromSimpleProductTest.xml @@ -80,7 +80,7 @@ <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addProductToShoppingCart1"> <argument name="productName" value="$$createProduct1.name$$"/> </actionGroup> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniShoppingCart1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="openMiniShoppingCart1"/> <see selector="{{StorefrontMinicartSection.productPriceByName($$createProduct1.name$$)}}" userInput="$$createProduct1.price$$" stepKey="seeCorrectProductPrice1"/> <!-- Assert that the rule isn't present on the Checkout page --> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml index 46ba6e30100b1..2df891b24223b 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml @@ -60,7 +60,7 @@ <actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage"> <argument name="productName" value="$createProduct.name$"/> </actionGroup> - <actionGroup ref="StorefrontOpenCartPageActionGroup" stepKey="openCartPage" /> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="openCartPage" /> <waitForElementVisible selector="{{CheckoutCartSummarySection.subtotal}}" stepKey="waitForSubtotalAppears"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$createProduct.price$" stepKey="seeProductPriceOnCartPage"/> </test> diff --git a/app/code/Magento/CatalogRuleConfigurable/Test/Mftf/Test/AdminApplyCatalogRuleForConfigurableProductWithAssignedSimpleProductsTest.xml b/app/code/Magento/CatalogRuleConfigurable/Test/Mftf/Test/AdminApplyCatalogRuleForConfigurableProductWithAssignedSimpleProductsTest.xml deleted file mode 100644 index e4dd65479b784..0000000000000 --- a/app/code/Magento/CatalogRuleConfigurable/Test/Mftf/Test/AdminApplyCatalogRuleForConfigurableProductWithAssignedSimpleProductsTest.xml +++ /dev/null @@ -1,271 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminApplyCatalogRuleForConfigurableProductWithAssignedSimpleProductsTest"> - <annotations> - <features value="CatalogRuleConfigurable"/> - <stories value="Apply catalog price rule"/> - <title value="DEPRECATED. Apply catalog rule for configurable product with assigned simple products"/> - <description value="DEPRECATED. Admin should be able to apply catalog rule for configurable product with assigned simple products"/> - <severity value="CRITICAL"/> - <testCaseId value="MC-14063"/> - <group value="catalogRuleConfigurable"/> - <group value="mtf_migrated"/> - <skip> - <issueId value="DEPRECATED">Use AdminApplyCatalogRuleForConfigurableProductWithAssignedSimpleProducts2Test instead</issueId> - </skip> - </annotations> - <before> - <!-- Create category for first configurable product --> - <createData entity="SimpleSubCategory" stepKey="firstSimpleCategory"/> - - <!-- Create first configurable product with two options --> - <createData entity="ApiConfigurableProduct" stepKey="createFirstConfigProduct"> - <requiredEntity createDataKey="firstSimpleCategory"/> - </createData> - - <createData entity="productAttributeWithTwoOptions" stepKey="createFirstConfigProductAttribute"/> - <createData entity="productAttributeOption1" stepKey="createFirstConfigProductAttributeFirstOption"> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - </createData> - <createData entity="productAttributeOption2" stepKey="createFirstConfigProductAttributeSecondOption"> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - </createData> - - <createData entity="AddToDefaultSet" stepKey="addFirstProductToAttributeSet"> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - </createData> - - <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getFirstConfigAttributeFirstOption"> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - </getData> - <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getFirstConfigAttributeSecondOption"> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - </getData> - - <!-- Create two child products for first configurable product --> - <createData entity="ApiSimpleOne" stepKey="createFirstConfigFirstChildProduct"> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - <requiredEntity createDataKey="getFirstConfigAttributeFirstOption"/> - </createData> - - <createData entity="ApiSimpleOne" stepKey="createFirstConfigSecondChildProduct"> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - <requiredEntity createDataKey="getFirstConfigAttributeSecondOption"/> - </createData> - - <createData entity="ConfigurableProductTwoOptions" stepKey="createFirstConfigProductOption"> - <requiredEntity createDataKey="createFirstConfigProduct"/> - <requiredEntity createDataKey="createFirstConfigProductAttribute"/> - <requiredEntity createDataKey="getFirstConfigAttributeFirstOption"/> - <requiredEntity createDataKey="getFirstConfigAttributeSecondOption"/> - </createData> - - <createData entity="ConfigurableProductAddChild" stepKey="createFirstConfigProductAddFirstChild"> - <requiredEntity createDataKey="createFirstConfigProduct"/> - <requiredEntity createDataKey="createFirstConfigFirstChildProduct"/> - </createData> - <createData entity="ConfigurableProductAddChild" stepKey="createFirstConfigProductAddSecondChild"> - <requiredEntity createDataKey="createFirstConfigProduct"/> - <requiredEntity createDataKey="createFirstConfigSecondChildProduct"/> - </createData> - - <!-- Add customizable options to first product --> - <updateData createDataKey="createFirstConfigProduct" entity="productWithOptionRadiobutton" stepKey="updateFirstProductWithOption"/> - - <!-- Create category for second configurable product --> - <createData entity="SimpleSubCategory" stepKey="secondSimpleCategory"/> - - <!-- Create second configurable product with two options --> - <createData entity="ApiConfigurableProduct" stepKey="createSecondConfigProduct"> - <requiredEntity createDataKey="secondSimpleCategory"/> - </createData> - - <createData entity="productAttributeWithTwoOptions" stepKey="createSecondConfigProductAttribute"/> - <createData entity="productAttributeOption1" stepKey="createSecondConfigProductAttributeFirstOption"> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - </createData> - <createData entity="productAttributeOption2" stepKey="createSecondConfigProductAttributeSecondOption"> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - </createData> - - <createData entity="AddToDefaultSet" stepKey="addSecondProductToAttributeSet"> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - </createData> - - <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getSecondConfigAttributeFirstOption"> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - </getData> - <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getSecondConfigAttributeSecondOption"> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - </getData> - - <!-- Create two child products for second configurable product --> - <createData entity="ApiSimpleOne" stepKey="createSecondConfigFirstChildProduct"> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - <requiredEntity createDataKey="getSecondConfigAttributeFirstOption"/> - </createData> - - <createData entity="ApiSimpleOne" stepKey="createSecondConfigSecondChildProduct"> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - <requiredEntity createDataKey="getSecondConfigAttributeSecondOption"/> - </createData> - - <createData entity="ConfigurableProductTwoOptions" stepKey="createSecondConfigProductOption"> - <requiredEntity createDataKey="createSecondConfigProduct"/> - <requiredEntity createDataKey="createSecondConfigProductAttribute"/> - <requiredEntity createDataKey="getSecondConfigAttributeFirstOption"/> - <requiredEntity createDataKey="getSecondConfigAttributeSecondOption"/> - </createData> - - <createData entity="ConfigurableProductAddChild" stepKey="createSecondConfigProductAddFirstChild"> - <requiredEntity createDataKey="createSecondConfigProduct"/> - <requiredEntity createDataKey="createSecondConfigFirstChildProduct"/> - </createData> - <createData entity="ConfigurableProductAddChild" stepKey="createSecondConfigProductAddSecondChild"> - <requiredEntity createDataKey="createSecondConfigProduct"/> - <requiredEntity createDataKey="createSecondConfigSecondChildProduct"/> - </createData> - - <!-- Add customizable options to second product --> - <updateData createDataKey="createSecondConfigProduct" entity="productWithOptionRadiobutton" stepKey="updateSecondProductWithOption"/> - - <!--Create customer group --> - <createData entity="CustomCustomerGroup" stepKey="customerGroup"/> - - <!-- Create Customer --> - <createData entity="SimpleUsCustomerWithNewCustomerGroup" stepKey="createCustomer"> - <requiredEntity createDataKey="customerGroup" /> - </createData> - - <!-- Login as Admin --> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminPanel"/> - </before> - <after> - <!-- Customer log out --> - <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogout"/> - - <!-- Delete created data --> - <deleteData createDataKey="createFirstConfigProduct" stepKey="deleteFirstConfigProduct"/> - <deleteData createDataKey="createFirstConfigFirstChildProduct" stepKey="deleteFirstConfigFirstChildProduct"/> - <deleteData createDataKey="createFirstConfigSecondChildProduct" stepKey="deleteFirstConfigSecondChildProduct"/> - <deleteData createDataKey="createFirstConfigProductAttribute" stepKey="deleteFirstConfigProductAttribute"/> - <deleteData createDataKey="firstSimpleCategory" stepKey="deleteFirstSimpleCategory"/> - - <deleteData createDataKey="createSecondConfigProduct" stepKey="deleteSecondConfigProduct"/> - <deleteData createDataKey="createSecondConfigFirstChildProduct" stepKey="deleteSecondConfigFirstChildProduct"/> - <deleteData createDataKey="createSecondConfigSecondChildProduct" stepKey="deleteSecondConfigSecondChildProduct"/> - <deleteData createDataKey="createSecondConfigProductAttribute" stepKey="deleteSecondConfigProductAttribute"/> - <deleteData createDataKey="secondSimpleCategory" stepKey="deleteSimpleCategory"/> - - <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> - <deleteData createDataKey="customerGroup" stepKey="deleteCustomerGroup"/> - - <!-- Delete created price rules --> - <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToPriceRulePage"/> - <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRuleForFirstOption"> - <argument name="name" value="{{CatalogRuleToFixed.name}}"/> - <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> - </actionGroup> - - <!-- Admin log out --> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - - <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> - </after> - <!-- Create price rule --> - <actionGroup ref="NewCatalogPriceRuleByUIActionGroup" stepKey="createPriceRule"> - <argument name="catalogRule" value="CatalogRuleToFixed"/> - </actionGroup> - <actionGroup ref="CatalogSelectCustomerGroupActionGroup" stepKey="addCustomerGroup"> - <argument name="customerGroupName" value="$$customerGroup.code$$"/> - </actionGroup> - - <!-- Save price rule --> - <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="clickSaveAndApplyRule"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the rule." stepKey="assertSuccessMessage"/> - - <!-- Run full reindex and clear caches --> - <magentoCLI command="indexer:reindex" stepKey="reindex"/> - <magentoCLI command="cache:flush" stepKey="flushCache"/> - - <!-- Login to storefront from customer --> - <actionGroup ref="LoginToStorefrontActionGroup" stepKey="logInFromCustomer"> - <argument name="Customer" value="$$createCustomer$$"/> - </actionGroup> - - <!-- Assert first product in category --> - <amOnPage url="$$firstSimpleCategory.name$$.html" stepKey="goToFirstCategoryPageStorefront"/> - <waitForPageLoad stepKey="waitForFirstCategoryPageLoad"/> - <actionGroup ref="StorefrontCheckCategoryConfigurableProductWithUpdatedPriceActionGroup" stepKey="checkFirstProductPriceInCategory"> - <argument name="productName" value="$$createFirstConfigProduct.name$$"/> - <argument name="expectedPrice" value="{{CatalogRuleToFixed.discount_amount}}"/> - </actionGroup> - - <!-- Assert second product in category --> - <amOnPage url="$$secondSimpleCategory.name$$.html" stepKey="goToSecondCategoryPageStorefront"/> - <waitForPageLoad stepKey="waitForSecondCategoryPageLoad"/> - <actionGroup ref="StorefrontCheckCategoryConfigurableProductWithUpdatedPriceActionGroup" stepKey="checkSecondProductPriceInCategory"> - <argument name="productName" value="$$createSecondConfigProduct.name$$"/> - <argument name="expectedPrice" value="{{CatalogRuleToFixed.discount_amount}}"/> - </actionGroup> - - <!-- Assert first product in storefront product page --> - <amOnPage url="$$createFirstConfigProduct.custom_attributes[url_key]$$.html" stepKey="amOnFirstProductPage"/> - <waitForPageLoad stepKey="waitForFirstProductPageLoad"/> - <actionGroup ref="StorefrontAssertUpdatedProductPriceInStorefrontProductPageActionGroup" stepKey="checkFirstProductPriceInStorefrontProductPage"> - <argument name="productName" value="$$createFirstConfigProduct.name$$"/> - <argument name="expectedPrice" value="{{CatalogRuleToFixed.discount_amount}}"/> - </actionGroup> - - <!-- Add first product with selected options to the cart --> - <actionGroup ref="StorefrontAddProductWithSelectedConfigurableAndCustomOptionsToCartActionGroup" stepKey="addFirstProductWithSelectedOptionToCart1"> - <argument name="product" value="$$createFirstConfigProduct$$"/> - <argument name="option" value="$$createFirstConfigProductAttributeFirstOption.option[store_labels][1][label]$$"/> - <argument name="customizableOption" value="{{ProductOptionValueRadioButtons1.title}}"/> - </actionGroup> - <grabTextFrom selector="{{StorefrontProductInfoMainSection.updatedPrice}}" stepKey="grabForthProductUpdatedPrice1"/> - - <actionGroup ref="StorefrontAddProductWithSelectedConfigurableAndCustomOptionsToCartActionGroup" stepKey="addFirstProductWithSelectedOptionToCart2"> - <argument name="product" value="$$createFirstConfigProduct$$"/> - <argument name="option" value="$$createFirstConfigProductAttributeSecondOption.option[store_labels][1][label]$$"/> - <argument name="customizableOption" value="{{ProductOptionValueRadioButtons3.title}}"/> - </actionGroup> - - <!-- Assert second product in storefront product page --> - <amOnPage url="$$createSecondConfigProduct.custom_attributes[url_key]$$.html" stepKey="amOnSecondProductPage"/> - <waitForPageLoad stepKey="waitForSecondProductPageLoad"/> - <actionGroup ref="StorefrontAssertUpdatedProductPriceInStorefrontProductPageActionGroup" stepKey="checkSecondProductPriceInStorefrontProductPage"> - <argument name="productName" value="$$createSecondConfigProduct.name$$"/> - <argument name="expectedPrice" value="{{CatalogRuleToFixed.discount_amount}}"/> - </actionGroup> - - <!-- Add second product with selected options to the cart --> - <actionGroup ref="StorefrontAddProductWithSelectedConfigurableAndCustomOptionsToCartActionGroup" stepKey="addSecondProductWithSelectedOptionToCart1"> - <argument name="product" value="$$createSecondConfigProduct$$"/> - <argument name="option" value="$$createSecondConfigProductAttributeFirstOption.option[store_labels][1][label]$$"/> - <argument name="customizableOption" value="{{ProductOptionValueRadioButtons1.title}}"/> - </actionGroup> - - <actionGroup ref="StorefrontAddProductWithSelectedConfigurableAndCustomOptionsToCartActionGroup" stepKey="addSecondProductWithSelectedOptionToCart2"> - <argument name="product" value="$$createSecondConfigProduct$$"/> - <argument name="option" value="$$createSecondConfigProductAttributeSecondOption.option[store_labels][1][label]$$"/> - <argument name="customizableOption" value="{{ProductOptionValueRadioButtons3.title}}"/> - </actionGroup> - - <!--Assert products prices in the cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPageLoad"/> - <see userInput="$210.69" selector="{{CheckoutCartProductSection.ProductPriceByOption($$createFirstConfigProductAttributeFirstOption.option[store_labels][1][label]$$)}}" stepKey="assertFirstProductPriceForFirstProductOption"/> - <see userInput="$120.70" selector="{{CheckoutCartProductSection.ProductPriceByOption($$createFirstConfigProductAttributeSecondOption.option[store_labels][1][label]$$)}}" stepKey="assertFirstProductPriceForSecondProductOption"/> - <see userInput="$210.69" selector="{{CheckoutCartProductSection.ProductPriceByOption($$createSecondConfigProductAttributeFirstOption.option[store_labels][1][label]$$)}}" stepKey="assertSecondProductPriceForFirstProductOption"/> - <see userInput="$120.70" selector="{{CheckoutCartProductSection.ProductPriceByOption($$createSecondConfigProductAttributeSecondOption.option[store_labels][1][label]$$)}}" stepKey="assertSecondProductPriceForSecondProductOption"/> - </test> -</tests> diff --git a/app/code/Magento/CatalogRuleConfigurable/Test/Mftf/Test/AdminApplyCatalogRuleForConfigurableProductWithOptionsTest.xml b/app/code/Magento/CatalogRuleConfigurable/Test/Mftf/Test/AdminApplyCatalogRuleForConfigurableProductWithOptionsTest.xml deleted file mode 100644 index 8ed9c6ad09dad..0000000000000 --- a/app/code/Magento/CatalogRuleConfigurable/Test/Mftf/Test/AdminApplyCatalogRuleForConfigurableProductWithOptionsTest.xml +++ /dev/null @@ -1,224 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminApplyCatalogRuleForConfigurableProductWithOptionsTest"> - <annotations> - <features value="CatalogRuleConfigurable"/> - <stories value="Apply catalog price rule"/> - <title value="DEPRECATED. Apply catalog price rule for configurable product with options"/> - <description value="DEPRECATED. Admin should be able to apply the catalog rule for configurable product with options"/> - <severity value="CRITICAL"/> - <testCaseId value="MC-14062"/> - <group value="catalogRuleConfigurable"/> - <group value="mtf_migrated"/> - <skip> - <issueId value="DEPRECATED">Use AdminApplyCatalogRuleForConfigurableProductWithOptions2Test instead</issueId> - </skip> - </annotations> - <before> - <!-- Create category --> - <createData entity="SimpleSubCategory" stepKey="simpleCategory"/> - - <!-- Create configurable product with three options --> - <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> - <requiredEntity createDataKey="simpleCategory"/> - </createData> - - <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> - <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeFirstOption"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeSecondOption"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - <createData entity="productAttributeOption3" stepKey="createConfigProductAttributeThirdOption"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - - <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </createData> - - <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeFirstOption"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </getData> - <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeSecondOption"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </getData> - <getData entity="ProductAttributeOptionGetter" index="3" stepKey="getConfigAttributeThirdOption"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - </getData> - - <!-- Create three child products --> - <createData entity="ApiSimpleOne" stepKey="createConfigFirstChildProduct"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeFirstOption"/> - </createData> - - <createData entity="ApiSimpleOne" stepKey="createConfigSecondChildProduct"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeSecondOption"/> - </createData> - - <createData entity="ApiSimpleOne" stepKey="createConfigThirdChildProduct"> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeThirdOption"/> - </createData> - - <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigProductAttribute"/> - <requiredEntity createDataKey="getConfigAttributeFirstOption"/> - <requiredEntity createDataKey="getConfigAttributeSecondOption"/> - <requiredEntity createDataKey="getConfigAttributeThirdOption"/> - </createData> - - <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddFirstChild"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigFirstChildProduct"/> - </createData> - <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddSecondChild"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigSecondChildProduct"/> - </createData> - <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddThirdChild"> - <requiredEntity createDataKey="createConfigProduct"/> - <requiredEntity createDataKey="createConfigThirdChildProduct"/> - </createData> - - <!-- Login as Admin --> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminPanel"/> - </before> - <after> - <!-- Delete created data --> - <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> - <deleteData createDataKey="createConfigFirstChildProduct" stepKey="deleteFirstSimpleProduct"/> - <deleteData createDataKey="createConfigSecondChildProduct" stepKey="deleteSecondSimpleProduct"/> - <deleteData createDataKey="createConfigThirdChildProduct" stepKey="deleteThirdSimpleProduct"/> - <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> - <deleteData createDataKey="simpleCategory" stepKey="deleteCategory"/> - - <!-- Delete created price rules --> - <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToPriceRulePage"/> - <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRuleForFirstOption"> - <argument name="name" value="{{CatalogRuleToFixed.name}}"/> - <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> - </actionGroup> - - <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRuleForSecondOption"> - <argument name="name" value="{{_defaultCatalogRule.name}}"/> - <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> - </actionGroup> - - <actionGroup ref="deleteEntitySecondaryGrid" stepKey="deletePriceRuleForThirdOption"> - <argument name="name" value="{{CatalogRuleWithoutDiscount.name}}"/> - <argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/> - </actionGroup> - - <!-- Log out --> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - - <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> - </after> - - <!-- Create price rule for first configurable product option --> - <actionGroup ref="NewCatalogPriceRuleByUIActionGroup" stepKey="createFirstPriceRule"> - <argument name="catalogRule" value="CatalogRuleToFixed"/> - </actionGroup> - <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroupForFirstPriceRule"/> - <actionGroup ref="CreateCatalogPriceRuleConditionWithAttributeAndOptionActionGroup" stepKey="createFirstCatalogPriceRuleCondition"> - <argument name="attributeName" value="$$createConfigProductAttribute.attribute[frontend_labels][0][label]$$"/> - <argument name="targetSelectValue" value="$$createConfigProductAttributeFirstOption.option[store_labels][1][label]$$"/> - <argument name="indexA" value="1"/> - <argument name="indexB" value="1"/> - </actionGroup> - <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="saveAndApplyFirstPriceRule"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the rule." stepKey="assertSuccessMessageForFirstPriceRule"/> - - <!-- Create price rule for second configurable product option --> - <actionGroup ref="NewCatalogPriceRuleByUIActionGroup" stepKey="createSecondPriceRule"> - <argument name="catalogRule" value="_defaultCatalogRule"/> - </actionGroup> - <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroupForSecondPriceRule"/> - <actionGroup ref="CreateCatalogPriceRuleConditionWithAttributeAndOptionActionGroup" stepKey="createSecondCatalogPriceRuleCondition"> - <argument name="attributeName" value="$$createConfigProductAttribute.attribute[frontend_labels][0][label]$$"/> - <argument name="targetSelectValue" value="$$createConfigProductAttributeSecondOption.option[store_labels][1][label]$$"/> - <argument name="indexA" value="1"/> - <argument name="indexB" value="1"/> - </actionGroup> - <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="saveAndApplySecondPriceRule"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the rule." stepKey="assertSuccessMessageForSecondPriceRule"/> - - <!-- Create price rule for third configurable product option --> - <actionGroup ref="NewCatalogPriceRuleByUIActionGroup" stepKey="createThirdPriceRule"> - <argument name="catalogRule" value="CatalogRuleWithoutDiscount"/> - </actionGroup> - <actionGroup ref="SelectNotLoggedInCustomerGroupActionGroup" stepKey="selectNotLoggedInCustomerGroupForThirdPriceRule"/> - <actionGroup ref="CreateCatalogPriceRuleConditionWithAttributeAndOptionActionGroup" stepKey="createThirdCatalogPriceRuleCondition"> - <argument name="attributeName" value="$$createConfigProductAttribute.attribute[frontend_labels][0][label]$$"/> - <argument name="targetSelectValue" value="$$createConfigProductAttributeThirdOption.option[store_labels][1][label]$$"/> - <argument name="indexA" value="1"/> - <argument name="indexB" value="1"/> - </actionGroup> - <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="saveAndApplyThirdPriceRule"/> - <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the rule." stepKey="assertSuccessMessageForThirdPriceRule"/> - - <!-- Run full reindex and clear caches --> - <magentoCLI command="indexer:reindex" stepKey="reindex"/> - <magentoCLI command="cache:flush" stepKey="flushCache"/> - - <!-- Assert product in storefront product page --> - <amOnPage url="$$createConfigProduct.custom_attributes[url_key]$$.html" stepKey="amOnProductPage"/> - <waitForPageLoad stepKey="waitForProductPageLoad"/> - <actionGroup ref="StorefrontAssertUpdatedProductPriceInStorefrontProductPageActionGroup" stepKey="assertUpdatedProductPriceInStorefrontProductPage"> - <argument name="productName" value="$$createConfigProduct.name$$"/> - <argument name="expectedPrice" value="{{CatalogRuleToFixed.discount_amount}}"/> - </actionGroup> - - <!-- Assert product options price in storefront product page --> - <actionGroup ref="StorefrontAssertCatalogPriceRuleAppliedToProductOptionActionGroup" stepKey="assertCatalogPriceRuleAppliedToFirstProductOption"> - <argument name="option" value="$$createConfigProductAttributeFirstOption.option[store_labels][1][label]$$"/> - <argument name="expectedPrice" value="{{CatalogRuleToFixed.discount_amount}}"/> - </actionGroup> - - <actionGroup ref="StorefrontAssertCatalogPriceRuleAppliedToProductOptionActionGroup" stepKey="assertCatalogPriceRuleAppliedToSecondProductOption"> - <argument name="option" value="$$createConfigProductAttributeSecondOption.option[store_labels][1][label]$$"/> - <argument name="expectedPrice" value="$110.70"/> - </actionGroup> - - <actionGroup ref="StorefrontAssertCatalogPriceRuleAppliedToProductOptionActionGroup" stepKey="assertCatalogPriceRuleAppliedToThirdProductOption"> - <argument name="option" value="$$createConfigProductAttributeThirdOption.option[store_labels][1][label]$$"/> - <argument name="expectedPrice" value="{{ApiConfigurableProduct.price}}"/> - </actionGroup> - - <!-- Add product with selected option to the cart --> - <actionGroup ref="StorefrontAddProductWithSelectedConfigurableOptionToCartActionGroup" stepKey="addProductWithSelectedFirstOptionToCart"> - <argument name="product" value="$$createConfigProduct$$"/> - <argument name="option" value="$$createConfigProductAttributeFirstOption.option[store_labels][1][label]$$"/> - </actionGroup> - - <actionGroup ref="StorefrontAddProductWithSelectedConfigurableOptionToCartActionGroup" stepKey="addProductWithSelectedSecondOptionToCart"> - <argument name="product" value="$$createConfigProduct$$"/> - <argument name="option" value="$$createConfigProductAttributeSecondOption.option[store_labels][1][label]$$"/> - </actionGroup> - - <actionGroup ref="StorefrontAddProductWithSelectedConfigurableOptionToCartActionGroup" stepKey="addProductWithSelectedThirdOptionToCart"> - <argument name="product" value="$$createConfigProduct$$"/> - <argument name="option" value="$$createConfigProductAttributeThirdOption.option[store_labels][1][label]$$"/> - </actionGroup> - - <!--Assert product price in the cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPageLoad"/> - <see userInput="{{CatalogRuleToFixed.discount_amount}}" selector="{{CheckoutCartProductSection.ProductPriceByOption($$createConfigProductAttributeFirstOption.option[store_labels][1][label]$$)}}" stepKey="assertProductPriceForFirstProductOption"/> - <see userInput="$110.70" selector="{{CheckoutCartProductSection.ProductPriceByOption($$createConfigProductAttributeSecondOption.option[store_labels][1][label]$$)}}" stepKey="assertProductPriceForSecondProductOption"/> - <see userInput="{{ApiConfigurableProduct.price}}" selector="{{CheckoutCartProductSection.ProductPriceByOption($$createConfigProductAttributeThirdOption.option[store_labels][1][label]$$)}}" stepKey="assertProductPriceForThirdProductOption"/> - </test> -</tests> diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php index 86dccf8cfe559..7b5d43ece922d 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/Attribute.php @@ -6,6 +6,11 @@ namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin; use Magento\CatalogSearch\Model\Indexer\Fulltext; +use Magento\Framework\Model\AbstractModel; +use Magento\Catalog\Model\ResourceModel\Attribute as AttributeResourceModel; +use Magento\Framework\Search\Request\Config; +use Magento\Framework\Indexer\IndexerRegistry; +use Magento\Catalog\Api\Data\EavAttributeInterface; /** * Catalog search indexer plugin for catalog attribute. @@ -13,7 +18,7 @@ class Attribute extends AbstractPlugin { /** - * @var \Magento\Framework\Search\Request\Config + * @var Config */ private $config; @@ -33,12 +38,12 @@ class Attribute extends AbstractPlugin private $saveIsNew; /** - * @param \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry - * @param \Magento\Framework\Search\Request\Config $config + * @param IndexerRegistry $indexerRegistry + * @param Config $config */ public function __construct( - \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, - \Magento\Framework\Search\Request\Config $config + IndexerRegistry $indexerRegistry, + Config $config ) { parent::__construct($indexerRegistry); $this->config = $config; @@ -47,36 +52,32 @@ public function __construct( /** * Check if indexer invalidation is needed on attribute save (searchable flag change) * - * @param \Magento\Catalog\Model\ResourceModel\Attribute $subject - * @param \Magento\Framework\Model\AbstractModel $attribute + * @param AttributeResourceModel $subject + * @param AbstractModel $attribute * * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function beforeSave( - \Magento\Catalog\Model\ResourceModel\Attribute $subject, - \Magento\Framework\Model\AbstractModel $attribute + AttributeResourceModel $subject, + AbstractModel $attribute ) { $this->saveIsNew = $attribute->isObjectNew(); - $this->saveNeedInvalidation = ( - $attribute->dataHasChangedFor('is_searchable') - || $attribute->dataHasChangedFor('is_filterable') - || $attribute->dataHasChangedFor('is_visible_in_advanced_search') - ); + $this->saveNeedInvalidation = $this->shouldInvalidateSearchIndex($attribute); } /** * Invalidate indexer on attribute save (searchable flag change) * - * @param \Magento\Catalog\Model\ResourceModel\Attribute $subject - * @param \Magento\Catalog\Model\ResourceModel\Attribute $result + * @param AttributeResourceModel $subject + * @param AttributeResourceModel $result * - * @return \Magento\Catalog\Model\ResourceModel\Attribute + * @return AttributeResourceModel * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterSave( - \Magento\Catalog\Model\ResourceModel\Attribute $subject, - \Magento\Catalog\Model\ResourceModel\Attribute $result + AttributeResourceModel $subject, + AttributeResourceModel $result ) { if ($this->saveNeedInvalidation) { $this->indexerRegistry->get(Fulltext::INDEXER_ID)->invalidate(); @@ -91,15 +92,15 @@ public function afterSave( /** * Check if indexer invalidation is needed on searchable attribute delete * - * @param \Magento\Catalog\Model\ResourceModel\Attribute $subject - * @param \Magento\Framework\Model\AbstractModel $attribute + * @param AttributeResourceModel $subject + * @param AbstractModel $attribute * * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function beforeDelete( - \Magento\Catalog\Model\ResourceModel\Attribute $subject, - \Magento\Framework\Model\AbstractModel $attribute + AttributeResourceModel $subject, + AbstractModel $attribute ) { $this->deleteNeedInvalidation = !$attribute->isObjectNew() && $attribute->getIsSearchable(); } @@ -107,19 +108,45 @@ public function beforeDelete( /** * Invalidate indexer on searchable attribute delete * - * @param \Magento\Catalog\Model\ResourceModel\Attribute $subject - * @param \Magento\Catalog\Model\ResourceModel\Attribute $result + * @param AttributeResourceModel $subject + * @param AttributeResourceModel $result * - * @return \Magento\Catalog\Model\ResourceModel\Attribute + * @return AttributeResourceModel * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterDelete( - \Magento\Catalog\Model\ResourceModel\Attribute $subject, - \Magento\Catalog\Model\ResourceModel\Attribute $result + AttributeResourceModel $subject, + AttributeResourceModel $result ) { if ($this->deleteNeedInvalidation) { $this->indexerRegistry->get(Fulltext::INDEXER_ID)->invalidate(); } return $result; } + + /** + * Check if catalogsearch_fulltext index should be invalidated. + * + * @param AbstractModel $attribute + * @return bool + */ + private function shouldInvalidateSearchIndex( + AbstractModel $attribute + ):bool { + $shouldInvalidate = false; + $fields = [ + EavAttributeInterface::IS_SEARCHABLE, + EavAttributeInterface::IS_FILTERABLE, + EavAttributeInterface::IS_VISIBLE_IN_ADVANCED_SEARCH, + ]; + foreach ($fields as $field) { + if ($this->saveIsNew && $attribute->getData($field) + || !$this->saveIsNew && $attribute->dataHasChangedFor($field)) { + $shouldInvalidate = true; + break; + } + } + + return $shouldInvalidate; + } } diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php index 3b0c4dfb6df2f..e2cb9174b5e97 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Decimal.php @@ -14,9 +14,6 @@ */ class Decimal extends AbstractFilter { - /** Decimal delta for filter */ - private const DECIMAL_DELTA = 0.001; - /** * @var \Magento\Framework\Pricing\PriceCurrencyInterface */ @@ -75,17 +72,11 @@ public function apply(\Magento\Framework\App\RequestInterface $request) list($from, $to) = explode('-', $filter); - // When the range is 10-20 we only need to get products that are in the 10-19.99 range. - $toValue = $to; - if (!empty($toValue) && $from !== $toValue) { - $toValue -= self::DECIMAL_DELTA; - } - $this->getLayer() ->getProductCollection() ->addFieldToFilter( $this->getAttributeModel()->getAttributeCode(), - ['from' => $from, 'to' => $toValue] + ['from' => $from, 'to' => $to] ); $this->getLayer()->getState()->addFilter( @@ -122,7 +113,7 @@ protected function _getItemsData() $from = ''; } if ($to == '*') { - $to = ''; + $to = null; } $label = $this->renderRangeLabel(empty($from) ? 0 : $from, $to); $value = $from . '-' . $to; @@ -149,7 +140,7 @@ protected function _getItemsData() protected function renderRangeLabel($fromPrice, $toPrice) { $formattedFromPrice = $this->priceCurrency->format($fromPrice); - if ($toPrice === '') { + if ($toPrice === null) { return __('%1 and above', $formattedFromPrice); } else { if ($fromPrice != $toPrice) { diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php index 66d9281ed38e2..332bb991bf29f 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php @@ -141,7 +141,7 @@ public function apply(\Magento\Framework\App\RequestInterface $request) list($from, $to) = $filter; $this->getLayer()->getProductCollection()->addFieldToFilter( - $this->getAttributeModel()->getAttributeCode(), + 'price', ['from' => $from, 'to' => empty($to) || $from == $to ? $to : $to - self::PRICE_DELTA] ); diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php index 5ac252677ff79..caa49d0f0c4a4 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php +++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php @@ -100,10 +100,7 @@ private function generateRequest($attributeType, $container, $useFulltext) ], ]; $bucketName = $attribute->getAttributeCode() . self::BUCKET_SUFFIX; - $generatorType = $attribute->getFrontendInput() === 'price' - ? $attribute->getFrontendInput() - : $attribute->getBackendType(); - $generator = $this->generatorResolver->getGeneratorForType($generatorType); + $generator = $this->generatorResolver->getGeneratorForType($attribute->getBackendType()); $request['filters'][$filterName] = $generator->getFilterData($attribute, $filterName); $request['aggregations'][$bucketName] = $generator->getAggregationData($attribute, $bucketName); } diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Price.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Price.php deleted file mode 100644 index 949806d14f45a..0000000000000 --- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Price.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogSearch\Model\Search\RequestGenerator; - -use Magento\Catalog\Model\ResourceModel\Eav\Attribute; -use Magento\Framework\Search\Request\BucketInterface; -use Magento\Framework\Search\Request\FilterInterface; - -/** - * Catalog search range request generator. - */ -class Price implements GeneratorInterface -{ - /** - * @inheritdoc - */ - public function getFilterData(Attribute $attribute, $filterName): array - { - return [ - 'type' => FilterInterface::TYPE_RANGE, - 'name' => $filterName, - 'field' => $attribute->getAttributeCode(), - 'from' => '$' . $attribute->getAttributeCode() . '.from$', - 'to' => '$' . $attribute->getAttributeCode() . '.to$', - ]; - } - - /** - * @inheritdoc - */ - public function getAggregationData(Attribute $attribute, $bucketName): array - { - return [ - 'type' => BucketInterface::TYPE_DYNAMIC, - 'name' => $bucketName, - 'field' => $attribute->getAttributeCode(), - 'method' => '$price_dynamic_algorithm$', - 'metric' => [['type' => 'count']], - ]; - } -} diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminDeleteSearchTermTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminDeleteSearchTermTest.xml index a950fb6c379cb..c376456a64ac4 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminDeleteSearchTermTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminDeleteSearchTermTest.xml @@ -20,7 +20,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="SimpleSubCategory" stepKey="initialCategoryEntity"/> <createData entity="SimpleProduct" stepKey="simpleProduct"> <requiredEntity createDataKey="initialCategoryEntity"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml deleted file mode 100644 index c8055d85c98ea..0000000000000 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml +++ /dev/null @@ -1,92 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="LayerNavigationOfCatalogSearchTest"> - <annotations> - <stories value="Search terms"/> - <title value="Layer Navigation of Catalog Search Should Equalize Price Range As Default Configuration"/> - <description value="Make sure filter of custom attribute with type of price displays on storefront Catalog page and price range should respect the configuration in Admin site"/> - <testCaseId value="MC-16979"/> - <useCaseId value="MC-16650"/> - <severity value="MAJOR"/> - <group value="CatalogSearch"/> - </annotations> - <before> - <magentoCLI command="config:set catalog/layered_navigation/price_range_calculation auto" stepKey="setAutoPriceRange"/> - <createData stepKey="createPriceAttribute" entity="productAttributeTypeOfPrice"/> - <createData stepKey="assignPriceAttributeGroup" entity="AddToDefaultSet"> - <requiredEntity createDataKey="createPriceAttribute"/> - </createData> - <createData entity="SimpleSubCategory" stepKey="subCategory"/> - <createData entity="SimpleProduct" stepKey="simpleProduct1"> - <requiredEntity createDataKey="subCategory"/> - </createData> - <createData entity="SimpleProduct" stepKey="simpleProduct2"> - <requiredEntity createDataKey="subCategory"/> - </createData> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> - </before> - <after> - <deleteData stepKey="deleteSimpleSubCategory" createDataKey="subCategory"/> - <deleteData stepKey="deleteSimpleProduct1" createDataKey="simpleProduct1"/> - <deleteData stepKey="deleteSimpleProduct2" createDataKey="simpleProduct2"/> - <deleteData createDataKey="createPriceAttribute" stepKey="deleteAttribute"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - </after> - <!--Update value for price attribute of Product 1--> - <comment userInput="Update value for price attribute of Product 1" stepKey="comment1"/> - <actionGroup ref="NavigateToCreatedProductEditPageActionGroup" stepKey="navigateToCreatedProductEditPage1"> - <argument name="product" value="$$simpleProduct1$$"/> - </actionGroup> - <grabTextFrom selector="{{AdminProductFormSection.attributeLabelByText($$createPriceAttribute.attribute[frontend_labels][0][label]$$)}}" stepKey="grabAttributeLabel"/> - <fillField selector="{{AdminProductAttributeSection.customAttribute($$createPriceAttribute.attribute_code$$)}}" userInput="30" stepKey="fillCustomPrice1"/> - <click selector="{{AdminProductFormSection.save}}" stepKey="clickSaveButton1"/> - <waitForPageLoad stepKey="waitForSimpleProductSaved1"/> - <!--Update value for price attribute of Product 2--> - <comment userInput="Update value for price attribute of Product 1" stepKey="comment2"/> - <actionGroup ref="NavigateToCreatedProductEditPageActionGroup" stepKey="navigateToCreatedProductEditPage2"> - <argument name="product" value="$$simpleProduct2$$"/> - </actionGroup> - <fillField selector="{{AdminProductAttributeSection.customAttribute($$createPriceAttribute.attribute_code$$)}}" userInput="70" stepKey="fillCustomPrice2"/> - <click selector="{{AdminProductFormSection.save}}" stepKey="clickSaveButton2"/> - <waitForPageLoad stepKey="waitForSimpleProductSaved2"/> - - <!--Run re-index task--> - <magentoCLI command="indexer:reindex" stepKey="reindex"/> - - <!--Navigate to category on Storefront--> - <comment userInput="Navigate to category on Storefront" stepKey="comment3"/> - <amOnPage url="{{StorefrontCategoryPage.url($$subCategory.name$$)}}" stepKey="goToCategoryStorefront"/> - <waitForPageLoad stepKey="waitForPageLoad"/> - <see userInput="{$grabAttributeLabel}" selector="{{StorefrontCategoryFilterSection.CustomPriceAttribute}}" stepKey="seePriceLayerNavigationOnStorefront"/> - </test> -</tests> - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/AttributeTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/AttributeTest.php index 70ae4a75924d4..fc2b353afaf03 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/AttributeTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Fulltext/Plugin/AttributeTest.php @@ -64,7 +64,7 @@ protected function setUp() ); $this->attributeMock = $this->createPartialMock( \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, - ['dataHasChangedFor', 'isObjectNew', 'getIsSearchable'] + ['dataHasChangedFor', 'isObjectNew', 'getIsSearchable', 'getData'] ); $this->config = $this->getMockBuilder(\Magento\Framework\Search\Request\Config::class) ->disableOriginalConstructor() @@ -85,7 +85,7 @@ public function testBeforeSave() ->method('isObjectNew') ->willReturn(true); $this->attributeMock->expects($this->once()) - ->method('dataHasChangedFor') + ->method('getData') ->with('is_searchable') ->willReturn(true); $this->assertEquals( @@ -102,22 +102,34 @@ public function testAfterSaveNoInvalidation() ); } - public function testAfterSaveWithInvalidation() + /** + * Test afterSave with invalidation. + * + * @param bool $saveNeedInvalidation + * @param bool $saveIsNew + * @dataProvider afterSaveDataProvider + */ + public function testAfterSaveWithInvalidation(bool $saveNeedInvalidation, bool $saveIsNew) { $model = $this->objectManager->getObject( Attribute::class, [ 'indexerRegistry' => $this->indexerRegistryMock, 'config' => $this->config, - 'saveNeedInvalidation' => true, - 'saveIsNew' => true + 'saveNeedInvalidation' => $saveNeedInvalidation, + 'saveIsNew' => $saveIsNew, ] ); - $this->indexerMock->expects($this->once())->method('invalidate'); - $this->prepareIndexer(); - $this->config->expects($this->once()) - ->method('reset'); + if ($saveNeedInvalidation) { + $this->indexerMock->expects($this->once())->method('invalidate'); + $this->prepareIndexer(); + } + + if ($saveIsNew || $saveNeedInvalidation) { + $this->config->expects($this->once()) + ->method('reset'); + } $this->assertEquals( $this->subjectMock, @@ -125,6 +137,19 @@ public function testAfterSaveWithInvalidation() ); } + /** + * @return array + */ + public function afterSaveDataProvider(): array + { + return [ + 'save_new_with_invalidation' => ['saveNeedInvalidation' => true, 'isNew' => true], + 'save_new_without_invalidation' => ['saveNeedInvalidation' => false, 'isNew' => true], + 'update_existing_with_inalidation' => ['saveNeedInvalidation' => true, 'isNew' => false], + 'update_existing_without_inalidation' => ['saveNeedInvalidation' => false, 'isNew' => false], + ]; + } + public function testBeforeDelete() { $this->attributeMock->expects($this->once()) diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php index f783f75a170e3..fc78c45af07a6 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php @@ -209,12 +209,6 @@ public function testApply() $priceId = '15-50'; $requestVar = 'test_request_var'; - $this->target->setAttributeModel($this->attribute); - $attributeCode = 'price'; - $this->attribute->expects($this->any()) - ->method('getAttributeCode') - ->will($this->returnValue($attributeCode)); - $this->target->setRequestVar($requestVar); $this->request->expects($this->exactly(1)) ->method('getParam') diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/PriceTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/PriceTest.php deleted file mode 100644 index 3635430197591..0000000000000 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/PriceTest.php +++ /dev/null @@ -1,82 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogSearch\Test\Unit\Model\Search\RequestGenerator; - -use Magento\Catalog\Model\ResourceModel\Eav\Attribute; -use Magento\CatalogSearch\Model\Search\RequestGenerator\Price; -use Magento\Framework\Search\Request\BucketInterface; -use Magento\Framework\Search\Request\FilterInterface; -use Magento\Framework\App\Config\ScopeConfigInterface; - -/** - * Test catalog search range request generator. - */ -class PriceTest extends \PHPUnit\Framework\TestCase -{ - /** @var Price */ - private $price; - - /** @var Attribute|\PHPUnit_Framework_MockObject_MockObject */ - private $attribute; - - /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - private $scopeConfigMock; - - protected function setUp() - { - $this->attribute = $this->getMockBuilder(Attribute::class) - ->disableOriginalConstructor() - ->setMethods(['getAttributeCode']) - ->getMockForAbstractClass(); - $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class) - ->setMethods(['getValue']) - ->getMockForAbstractClass(); - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->price = $objectManager->getObject( - Price::class, - ['scopeConfig' => $this->scopeConfigMock] - ); - } - - public function testGetFilterData() - { - $filterName = 'test_filter_name'; - $attributeCode = 'test_attribute_code'; - $expected = [ - 'type' => FilterInterface::TYPE_RANGE, - 'name' => $filterName, - 'field' => $attributeCode, - 'from' => '$' . $attributeCode . '.from$', - 'to' => '$' . $attributeCode . '.to$', - ]; - $this->attribute->expects($this->atLeastOnce()) - ->method('getAttributeCode') - ->willReturn($attributeCode); - $actual = $this->price->getFilterData($this->attribute, $filterName); - $this->assertEquals($expected, $actual); - } - - public function testGetAggregationData() - { - $bucketName = 'test_bucket_name'; - $attributeCode = 'test_attribute_code'; - $method = 'price_dynamic_algorithm'; - $expected = [ - 'type' => BucketInterface::TYPE_DYNAMIC, - 'name' => $bucketName, - 'field' => $attributeCode, - 'method' => '$'. $method . '$', - 'metric' => [['type' => 'count']], - ]; - $this->attribute->expects($this->atLeastOnce()) - ->method('getAttributeCode') - ->willReturn($attributeCode); - $actual = $this->price->getAggregationData($this->attribute, $bucketName); - $this->assertEquals($expected, $actual); - } -} diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml index 4e5b38878ee52..43ebded020ec1 100644 --- a/app/code/Magento/CatalogSearch/etc/di.xml +++ b/app/code/Magento/CatalogSearch/etc/di.xml @@ -284,7 +284,6 @@ <argument name="defaultGenerator" xsi:type="object">\Magento\CatalogSearch\Model\Search\RequestGenerator\General</argument> <argument name="generators" xsi:type="array"> <item name="decimal" xsi:type="object">Magento\CatalogSearch\Model\Search\RequestGenerator\Decimal</item> - <item name="price" xsi:type="object">Magento\CatalogSearch\Model\Search\RequestGenerator\Price</item> </argument> </arguments> </type> diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml index dec157484dfef..213099d3ba974 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml @@ -57,7 +57,7 @@ <argument name="categoryName" value="admin"/> <argument name="categoryUrlKey" value="{{SimpleSubCategory.name}}"/> </actionGroup> - <see selector="{{AdminMessagesSection.success}}" userInput="You saved the category." stepKey="seeAdminSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="seeAdminSuccessMessage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('admin')}}" stepKey="seeAdminCategoryInTree"/> <!--Check category creation with restricted url key 'soap'--> <comment userInput="Check category creation with restricted url key 'soap'" stepKey="commentCheckSoapCategoryCreation"/> @@ -78,7 +78,7 @@ <argument name="categoryName" value="soap"/> <argument name="categoryUrlKey" value="{{ApiCategory.name}}"/> </actionGroup> - <see selector="{{AdminMessagesSection.success}}" userInput="You saved the category." stepKey="seeSoapSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="seeSoapSuccessMessage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('soap')}}" stepKey="seeSoapCategoryInTree"/> <!--Check category creation with restricted url key 'rest'--> <comment userInput="Check category creation with restricted url key 'rest'" stepKey="commentCheckRestCategoryCreation"/> @@ -99,7 +99,7 @@ <argument name="categoryName" value="rest"/> <argument name="categoryUrlKey" value="{{SubCategoryWithParent.name}}"/> </actionGroup> - <see selector="{{AdminMessagesSection.success}}" userInput="You saved the category." stepKey="seeRestSuccessMesdgssage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="seeRestSuccessMesdgssage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('rest')}}" stepKey="seeRestCategoryInTree"/> <!--Check category creation with restricted url key 'graphql'--> <comment userInput="Check category creation with restricted url key 'graphql'" stepKey="commentCheckGraphQlCategoryCreation"/> @@ -120,7 +120,7 @@ <argument name="categoryName" value="graphql"/> <argument name="categoryUrlKey" value="{{NewSubCategoryWithParent.name}}"/> </actionGroup> - <see selector="{{AdminMessagesSection.success}}" userInput="You saved the category." stepKey="seeGraphQlSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="seeGraphQlSuccessMessage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('graphql')}}" stepKey="seeGraphQlCategoryInTree"/> </test> </tests> diff --git a/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php b/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php index 10791eae5405f..9567f78414d78 100644 --- a/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php +++ b/app/code/Magento/CatalogUrlRewrite/Ui/DataProvider/Product/Form/Modifier/ProductUrlRewrite.php @@ -125,6 +125,7 @@ protected function addUrlRewriteCheckbox(array $meta) 'handleUseDefault' => '${ $.parentName }.url_key:isUseDefault', 'handleChanges' => '${ $.provider }:data.product.' . ProductAttributeInterface::CODE_SEO_FIELD_URL_KEY, + '__disableTmpl' => ['urlKey' => false, 'handleUseDefault' => false, 'handleChanges' => false], ], 'description' => __('Create Permanent Redirect for old URL'), 'dataScope' => 'url_key_create_redirect', diff --git a/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml index 288134a889db0..59f0cd7437f44 100644 --- a/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml +++ b/app/code/Magento/CatalogWidget/Test/Mftf/Test/CatalogProductListWidgetOperatorsTest.xml @@ -73,7 +73,7 @@ <selectOption stepKey="selectStaticBlockOnlyOption" userInput="Static block only" selector="{{AdminCategoryDisplaySettingsSection.displayMode}}"/> <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryWithProducts"/> <waitForPageLoad stepKey="waitForCategorySaved"/> - <see userInput="You saved the category." stepKey="seeSuccessMessage"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="seeSuccessMessage"/> <!--Go to Storefront > category--> <amOnPage url="$$simplecategory.name$$.html" stepKey="goToStorefrontCategoryPage"/> diff --git a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php index 00cc06ea0ff47..16450ec6ff2c2 100644 --- a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php +++ b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php @@ -299,6 +299,7 @@ private function getBillingAddressComponent($paymentCode, $elements) 'deps' => 'checkoutProvider', 'dataScopePrefix' => 'billingAddress' . $paymentCode, 'billingAddressListProvider' => '${$.name}.billingAddressList', + '__disableTmpl' => ['billingAddressListProvider' => false], 'sortOrder' => 1, 'children' => [ 'billingAddressList' => [ @@ -329,6 +330,7 @@ private function getBillingAddressComponent($paymentCode, $elements) ], 'filterBy' => [ 'target' => '${ $.provider }:${ $.parentScope }.country_id', + '__disableTmpl' => ['target' => false], 'field' => 'country_id', ], ], diff --git a/app/code/Magento/Checkout/Model/Layout/DepersonalizePlugin.php b/app/code/Magento/Checkout/Model/Layout/DepersonalizePlugin.php index de36bf658c59d..2f39cb6907661 100644 --- a/app/code/Magento/Checkout/Model/Layout/DepersonalizePlugin.php +++ b/app/code/Magento/Checkout/Model/Layout/DepersonalizePlugin.php @@ -3,50 +3,54 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Checkout\Model\Layout; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Framework\View\LayoutInterface; use Magento\PageCache\Model\DepersonalizeChecker; /** - * Class DepersonalizePlugin + * Depersonalize customer data. + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class DepersonalizePlugin { /** * @var DepersonalizeChecker */ - protected $depersonalizeChecker; + private $depersonalizeChecker; /** - * @var \Magento\Checkout\Model\Session + * @var CheckoutSession */ - protected $checkoutSession; + private $checkoutSession; /** * @param DepersonalizeChecker $depersonalizeChecker - * @param \Magento\Checkout\Model\Session $checkoutSession + * @param CheckoutSession $checkoutSession * @codeCoverageIgnore */ public function __construct( DepersonalizeChecker $depersonalizeChecker, - \Magento\Checkout\Model\Session $checkoutSession + CheckoutSession $checkoutSession ) { - $this->checkoutSession = $checkoutSession; $this->depersonalizeChecker = $depersonalizeChecker; + $this->checkoutSession = $checkoutSession; } /** - * After generate Xml + * Change sensitive customer data if the depersonalization is needed. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @param \Magento\Framework\View\LayoutInterface $result - * @return \Magento\Framework\View\LayoutInterface + * @param LayoutInterface $subject + * @return void */ - public function afterGenerateXml(\Magento\Framework\View\LayoutInterface $subject, $result) + public function afterGenerateElements(LayoutInterface $subject) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->checkoutSession->clearStorage(); } - return $result; } } diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontAddSimpleProductToCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontAddSimpleProductToCartActionGroup.xml index a17a6b4353783..d6add9a5d5c00 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontAddSimpleProductToCartActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontAddSimpleProductToCartActionGroup.xml @@ -11,12 +11,12 @@ <!-- Add Product to Cart from the category page and check message --> <actionGroup name="StorefrontAddSimpleProductToCartActionGroup"> <annotations> - <description>Adds the provided Product to the Storefront Shopping Cart from a Storefront Category page. Validates that the provided Success Message is present and correct.</description> + <description>Only works on Storefront Category Page - Add Simple Product to Cart</description> </annotations> <arguments> <argument name="product" type="entity"/> </arguments> - + <moveMouseOver selector="{{StorefrontCategoryProductSection.ProductInfoByName(product.name)}}" stepKey="moveMouseOverProduct"/> <click selector="{{StorefrontCategoryProductSection.ProductAddToCartByName(product.name)}}" stepKey="clickAddToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" stepKey="waitForSuccessMessage"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontOpenCartPageActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontCartPageOpenActionGroup.xml similarity index 89% rename from app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontOpenCartPageActionGroup.xml rename to app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontCartPageOpenActionGroup.xml index fe1e48e00c5bb..67301ce96c40b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontOpenCartPageActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontCartPageOpenActionGroup.xml @@ -7,7 +7,7 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="StorefrontOpenCartPageActionGroup"> + <actionGroup name="StorefrontCartPageOpenActionGroup"> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="openCartPage" /> <waitForPageLoad stepKey="waitForPageLoaded" /> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontSelectOptionDropDownActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontSelectOptionDropDownActionGroup.xml deleted file mode 100644 index fa169373c1096..0000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontSelectOptionDropDownActionGroup.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="StorefrontSelectOptionDropDownActionGroup"> - <annotations> - <description>DEPRECATED. Please use StorefrontProductPageSelectDropDownOptionValueActionGroup instead. Selects the provided Product Option Value under the provided Product Option Title on a Storefront Product page.</description> - </annotations> - <arguments> - <argument name="optionTitle" defaultValue="ProductOptionDropDown"/> - <argument name="option" defaultValue="ProductOptionValueDropdown2.title"/> - </arguments> - - <selectOption selector="{{StorefrontProductInfoMainSection.productOptionSelect(optionTitle.title)}}" userInput="{{option}}" stepKey="fillOptionDropDown"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutSpecificDestinationsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutSpecificDestinationsTest.xml index 58a44f5b89f90..561e73bc24f61 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutSpecificDestinationsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckoutSpecificDestinationsTest.xml @@ -48,8 +48,7 @@ </actionGroup> <!--Go to shopping cart--> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnPageShoppingCart"/> - + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnPageShoppingCart"/> <!--Verify country options in checkout top destination section--> <actionGroup ref="VerifyTopDestinationsCountryActionGroup" stepKey="verifyTopDestinationsCountry"> <argument name="country" value="Bahamas"/> @@ -68,7 +67,7 @@ </actionGroup> <!--Go to shopping cart--> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnPageShoppingCart2"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnPageShoppingCart2"/> <!--Verify country options is shown by default--> <actionGroup ref="VerifyTopDestinationsCountryActionGroup" stepKey="verifyTopDestinationsCountry2"> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml index ef5f5b640b0a2..5fd201290655a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleDynamicProductFromShoppingCartTest.xml @@ -60,8 +60,7 @@ </actionGroup> <!-- Remove product from cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <actionGroup ref="DeleteProductFromShoppingCartActionGroup" stepKey="deleteProduct"> <argument name="productName" value="$$createBundleDynamicProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleFixedProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleFixedProductFromShoppingCartTest.xml index e141d0628cc4d..603ee1ecea4df 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleFixedProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteBundleFixedProductFromShoppingCartTest.xml @@ -52,8 +52,7 @@ </actionGroup> <!-- Remove product from cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <actionGroup ref="DeleteProductFromShoppingCartActionGroup" stepKey="deleteProduct"> <argument name="productName" value="$$createFixedBundleProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteConfigurableProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteConfigurableProductFromShoppingCartTest.xml index 62fa3063de08a..e7b61415723cc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteConfigurableProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteConfigurableProductFromShoppingCartTest.xml @@ -74,8 +74,7 @@ </actionGroup> <!-- Remove product from cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <actionGroup ref="DeleteProductFromShoppingCartActionGroup" stepKey="deleteProduct"> <argument name="productName" value="$$createConfigProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml index 988e3b8d3129d..93fd115ae8577 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml @@ -44,8 +44,7 @@ </actionGroup> <!-- Remove product from cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <actionGroup ref="DeleteProductFromShoppingCartActionGroup" stepKey="deleteProduct"> <argument name="productName" value="$$createDownloadableProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteGroupedProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteGroupedProductFromShoppingCartTest.xml index eb8e753ea0b79..b82df28ebb95f 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteGroupedProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteGroupedProductFromShoppingCartTest.xml @@ -58,8 +58,7 @@ </actionGroup> <!-- Remove products from cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <click selector="{{CheckoutCartProductSection.removeProductByName($$createFirstSimpleProduct.name$$)}}" stepKey="deleteFirstProductFromCheckoutCart"/> <click selector="{{CheckoutCartProductSection.removeProductByName($$createSecondSimpleProduct.name$$)}}" stepKey="deleteSecondProductFromCheckoutCart"/> <click selector="{{CheckoutCartProductSection.removeProductByName($$createThirdSimpleProduct.name$$)}}" stepKey="deleteThirdProductFromCheckoutCart"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteVirtualProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteVirtualProductFromShoppingCartTest.xml index 969a827a8a461..39b4e66ef9f07 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteVirtualProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteVirtualProductFromShoppingCartTest.xml @@ -38,8 +38,7 @@ </actionGroup> <!-- Remove product from cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <actionGroup ref="DeleteProductFromShoppingCartActionGroup" stepKey="deleteProduct"> <argument name="productName" value="$$createVirtualProduct.name$$"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/IdentityOfDefaultBillingAndShippingAddressTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/IdentityOfDefaultBillingAndShippingAddressTest.xml index e2d1a1b9139c8..c3713206ed1d2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/IdentityOfDefaultBillingAndShippingAddressTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/IdentityOfDefaultBillingAndShippingAddressTest.xml @@ -31,8 +31,14 @@ <amOnPage url="" stepKey="DoToStorefront"/> <!-- Fill out form for a new user with address --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="signUpNewUser"> - <argument name="Customer" value="Simple_US_Customer_NY"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <!-- Add simple product to cart --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml index fd6656b1d1b28..ceaf72fff83bb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml @@ -41,17 +41,16 @@ <see selector="{{StorefrontCategoryMainSection.SuccessMsg}}" userInput="You added $$createSimpleProduct.name$$ to your shopping cart." stepKey="seeAddedToCartMessage"/> <see selector="{{StorefrontMinicartSection.quantity}}" userInput="1" stepKey="seeCartQuantity"/> <!-- open the minicart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickShowMinicart1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickShowMinicart1"/> <click selector="{{StorefrontMinicartSection.viewAndEditCart}}" stepKey="editProductFromMiniCart"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickShowMinicart2"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickShowMinicart2"/> <click selector="{{StorefrontMinicartSection.deleteMiniCartItem}}" stepKey="deleteMiniCartItem"/> <waitForElementVisible selector="{{StoreFrontRemoveItemModalSection.message}}" stepKey="waitFortheConfirmationModal"/> <see selector="{{StoreFrontRemoveItemModalSection.message}}" userInput="Are you sure you would like to remove this item from the shopping cart?" stepKey="seeDeleteConfirmationMessage"/> <click selector="{{StoreFrontRemoveItemModalSection.ok}}" stepKey="confirmDelete"/> <waitForPageLoad stepKey="waitForDeleteToFinish"/> <dontSeeElement selector="{{CheckoutCartProductSection.RemoveItem}}" stepKey="dontSeeDeleteProductFromCheckoutCart"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/> - <waitForPageLoad stepKey="WaitForPageLoad3"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> <see userInput="You have no items in your shopping cart." stepKey="seeNoItemsInShoppingCart"/> </test> </tests> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/ShoppingCartAndMiniShoppingCartPerCustomerTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/ShoppingCartAndMiniShoppingCartPerCustomerTest.xml index 741fde91f851e..571aa24209389 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/ShoppingCartAndMiniShoppingCartPerCustomerTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/ShoppingCartAndMiniShoppingCartPerCustomerTest.xml @@ -75,9 +75,9 @@ <waitForPageLoad stepKey="waitForSecondProductPageLoad"/> <!-- Fill the custom options values --> - <actionGroup ref="StorefrontSelectOptionDropDownActionGroup" stepKey="selectFirstOption"> - <argument name="optionTitle" value="ProductOptionValueDropdown"/> - <argument name="option" value="ProductOptionValueWithSkuDropdown1.title"/> + <actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectFirstOption"> + <argument name="attributeLabel" value="{{ProductOptionValueDropdown.title}}"/> + <argument name="optionLabel" value="{{ProductOptionValueWithSkuDropdown1.title}}"/> </actionGroup> <fillField selector="{{StorefrontProductInfoMainSection.productOptionFieldInput(ProductOptionField.title)}}" userInput="OptionField" stepKey="fillProductOptionInputField"/> @@ -115,8 +115,7 @@ <argument name="Customer" value="$$createFirstCustomer$$"/> </actionGroup> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnPageShoppingCart"/> - <waitForPageLoad stepKey="waitForCheckoutPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnPageShoppingCart"/> <!-- Assert first products present in shopping cart --> <actionGroup ref="StorefrontCheckCartSimpleProductActionGroup" stepKey="checkFirstProductInCart"> @@ -155,8 +154,7 @@ </actionGroup> <!-- Assert first products present in shopping cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnShoppingCartPage"/> <actionGroup ref="StorefrontCheckCartSimpleProductActionGroup" stepKey="checkProductInCart"> <argument name="product" value="$$createSimpleProduct$$"/> <argument name="productQuantity" value="quoteQty2Price123.qty"/> @@ -168,8 +166,7 @@ <!-- Assert product in mini cart --> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToHomePage"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertProductInMiniCart"> <argument name="productName" value="$$createSimpleProduct.name$$"/> <argument name="productPrice" value="$$createSimpleProduct.price$$"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontFreeShippingRecalculationAfterCouponCodeAddedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontFreeShippingRecalculationAfterCouponCodeAddedTest.xml index 57ed8e442af7c..af3a2e6870cd7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontFreeShippingRecalculationAfterCouponCodeAddedTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontFreeShippingRecalculationAfterCouponCodeAddedTest.xml @@ -64,8 +64,7 @@ <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart1"/> <waitForPageLoad stepKey="waitForpageLoad1"/> <dontSee selector="{{CheckoutShippingMethodsSection.shippingMethodRowByName('Free')}}" stepKey="dontSeeFreeShipping"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage"/> <conditionalClick selector="{{DiscountSection.DiscountTab}}" dependentSelector="{{DiscountSection.CouponInput}}" visible="false" stepKey="clickIfDiscountTabClosed1"/> <waitForPageLoad stepKey="waitForCouponTabOpen1"/> <click selector="{{DiscountSection.CancelCoupon}}" stepKey="cancelCoupon"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontUpdateShoppingCartWhileUpdateMinicartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontUpdateShoppingCartWhileUpdateMinicartTest.xml index f7ae9d29ada55..1f9948f80f391 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontUpdateShoppingCartWhileUpdateMinicartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StoreFrontUpdateShoppingCartWhileUpdateMinicartTest.xml @@ -45,7 +45,7 @@ </assertEquals> <!--Open minicart and change Qty--> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="openMiniCart"/> <waitForElementVisible selector="{{StorefrontMinicartSection.quantity}}" stepKey="waitForElementQty"/> <pressKey selector="{{StorefrontMinicartSection.itemQuantity($$createProduct.name$$)}}" parameterArray="[\Facebook\WebDriver\WebDriverKeys::BACKSPACE]" stepKey="deleteFiled"/> <fillField selector="{{StorefrontMinicartSection.itemQuantity($$createProduct.name$$)}}" userInput="5" stepKey="changeQty"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddBundleDynamicProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddBundleDynamicProductToShoppingCartTest.xml index 5e5278a256194..e82f3c0588835 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddBundleDynamicProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddBundleDynamicProductToShoppingCartTest.xml @@ -111,8 +111,7 @@ </actionGroup> <!-- Assert Product in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertSimpleProduct3MiniCart"> <argument name="productName" value="$$createBundleProduct.name$$"/> <argument name="productPrice" value="$50.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddConfigurableProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddConfigurableProductToShoppingCartTest.xml index b8e70d7492539..21e785de6cab3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddConfigurableProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddConfigurableProductToShoppingCartTest.xml @@ -157,8 +157,7 @@ </actionGroup> <!-- Assert product details in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertMiniCart"> <argument name="productName" value="$$createConfigProduct.name$$"/> <argument name="productPrice" value="$$createConfigChildProduct2.price$$"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml index e098c15c0eb6a..bbc0a29000a77 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml @@ -77,8 +77,7 @@ </actionGroup> <!-- Assert product details in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertMiniCart"> <argument name="productName" value="$$createDownloadableProduct.name$$"/> <argument name="productPrice" value="$123.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddGroupedProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddGroupedProductToShoppingCartTest.xml index 0fc4cee5e0582..3e2f32a4ab055 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddGroupedProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddGroupedProductToShoppingCartTest.xml @@ -101,8 +101,7 @@ </actionGroup> <!-- Assert product1 details in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertSimpleProduct3MiniCart"> <argument name="productName" value="$$simple3.name$$"/> <argument name="productPrice" value="$300.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddProductWithAllTypesOfCustomOptionToTheShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddProductWithAllTypesOfCustomOptionToTheShoppingCartTest.xml index 8081abcff307b..e8a72b6e88109 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddProductWithAllTypesOfCustomOptionToTheShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddProductWithAllTypesOfCustomOptionToTheShoppingCartTest.xml @@ -48,7 +48,10 @@ <actionGroup ref="StorefrontAttachOptionFileActionGroup" stepKey="selectAndAttachFile"/> <!--Select Option From DropDown option --> - <actionGroup ref="StorefrontSelectOptionDropDownActionGroup" stepKey="selectDropDownOption"/> + <actionGroup ref="StorefrontProductPageSelectDropDownOptionValueActionGroup" stepKey="selectFirstOption"> + <argument name="attributeLabel" value="{{ProductOptionDropDown.title}}"/> + <argument name="optionLabel" value="{{ProductOptionValueDropdown2.title}}"/> + </actionGroup> <scrollTo selector="{{StorefrontProductInfoMainSection.customOptionLabel(ProductOptionMultiSelect.title)}}" stepKey="scrollToMultiSelect"/> <!-- Select CheckBox From CheckBox option --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddTwoBundleMultiSelectOptionsToTheShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddTwoBundleMultiSelectOptionsToTheShoppingCartTest.xml index 14788250a9bca..265f9a7cbbc98 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddTwoBundleMultiSelectOptionsToTheShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddTwoBundleMultiSelectOptionsToTheShoppingCartTest.xml @@ -112,8 +112,7 @@ </actionGroup> <!-- Assert Product in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertSimpleProduct3MiniCart"> <argument name="productName" value="$$createBundleProduct.name$$"/> <argument name="productPrice" value="$60.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml index e4eb53a1f1925..3648ac361ccc9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontApplyPromoCodeDuringCheckoutTest.xml @@ -83,8 +83,8 @@ <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="filterOrderById"> <argument name="orderId" value="$grabOrderNumber"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForAdminOrderPageLoad"/> + + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <scrollTo selector="{{AdminOrderTotalSection.grandTotal}}" stepKey="scrollToOrderTotalSection"/> <see selector="{{AdminOrderTotalSection.grandTotal}}" userInput="$$createProduct.price$$" stepKey="checkTotal"/> </test> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckPagerShoppingCartWithMoreThan20ProductsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckPagerShoppingCartWithMoreThan20ProductsTest.xml index caec34c5ef1aa..93d1c4092c05e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckPagerShoppingCartWithMoreThan20ProductsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckPagerShoppingCartWithMoreThan20ProductsTest.xml @@ -131,7 +131,7 @@ <deleteData createDataKey="simpleProduct20" stepKey="deleteCartItem20"/> <deleteData createDataKey="simpleProduct21" stepKey="deleteCartItem21"/> </after> - <actionGroup ref="StorefrontOpenCartPageActionGroup" stepKey="goToCartPage" /> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage" /> <actionGroup ref="AssertToolbarTextIsVisibleInCartActionGroup" stepKey="VerifyPagerText"> <argument name="text" value="Items 1 to 20 of 21 total"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml index 444ebf653b94f..27d4e4c207ae7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckoutDisabledBundleProductTest.xml @@ -71,7 +71,7 @@ </actionGroup> <closeTab stepKey="closeTab"/> <!-- Go to cart page--> - <actionGroup ref="StorefrontOpenCartPageActionGroup" stepKey="openCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="openCartPage"/> <!-- Assert checkout button exists on the page--> <seeElement selector="{{CheckoutCartSummarySection.proceedToCheckout}}" stepKey="seeCheckoutButton"/> <!-- Assert no error message is not shown on the page--> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml index 9152949fbf2a1..27597a72fdb7f 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerLoginDuringCheckoutTest.xml @@ -41,7 +41,15 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> <!-- Go to Storefront as Guest and create new account --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="createNewCustomerAccount"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> + </actionGroup> <!-- Sign Out --> <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogout"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteBundleProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteBundleProductFromMiniShoppingCartTest.xml index fe320fb276c8a..d116d0049c9df 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteBundleProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteBundleProductFromMiniShoppingCartTest.xml @@ -65,8 +65,7 @@ <waitForPageLoad stepKey="waitForMiniCartPanelToAppear"/> <!-- Assert Product in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertSimpleProduct3MiniCart"> <argument name="productName" value="$$createBundleProduct.name$$"/> <argument name="productPrice" value="$10.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml index 3c234602df17a..8a52fa7740b95 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml @@ -49,8 +49,7 @@ <actionGroup ref="ClickViewAndEditCartFromMiniCartActionGroup" stepKey="selectViewAndEditCart"/> <!-- Assert product details in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertMiniCart"> <argument name="productName" value="$$createDownloadableProduct.name$$"/> <argument name="productPrice" value="$123.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleAndVirtualProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleAndVirtualProductFromMiniShoppingCartTest.xml index 643c6d8c14dd7..21966875519dc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleAndVirtualProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleAndVirtualProductFromMiniShoppingCartTest.xml @@ -47,8 +47,7 @@ </actionGroup> <!-- Assert Simple and Virtual products in mini cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertSimpleProductInMiniCart"> <argument name="productName" value="$$simpleProduct.name$$"/> <argument name="productPrice" value="$10.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleProductFromMiniShoppingCartTest.xml index a7bb3d927f620..effd376ab4bfb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteSimpleProductFromMiniShoppingCartTest.xml @@ -36,8 +36,7 @@ </actionGroup> <!-- Assert Product in Mini Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickOnMiniCart"/> - <waitForPageLoad stepKey="waitForPageToLoad1"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickOnMiniCart"/> <actionGroup ref="AssertStorefrontMiniCartItemsActionGroup" stepKey="assertSimpleProduct3MiniCart"> <argument name="productName" value="$$simpleProduct.name$$"/> <argument name="productPrice" value="$10.00"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml index 5c06f9ed55067..0d69306a4b1ba 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest/StorefrontGuestCheckoutTest.xml @@ -64,8 +64,7 @@ <fillField selector="{{AdminOrdersGridSection.search}}" userInput="{$grabOrderNumber}" stepKey="fillOrderNum"/> <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearchOrderNum"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappearOnSearch"/> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeAdminOrderStatus"/> <see selector="{{AdminOrderDetailsInformationSection.accountInformation}}" userInput="{{CustomerEntityOne.fullname}}" stepKey="seeAdminOrderGuest"/> <see selector="{{AdminOrderDetailsInformationSection.accountInformation}}" userInput="{{CustomerEntityOne.email}}" stepKey="seeAdminOrderEmail"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontMissingPagerShoppingCartWith20ProductsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontMissingPagerShoppingCartWith20ProductsTest.xml index 32b0985c290a3..a5a3675ea0a0b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontMissingPagerShoppingCartWith20ProductsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontMissingPagerShoppingCartWith20ProductsTest.xml @@ -126,7 +126,7 @@ <deleteData createDataKey="simpleProduct20" stepKey="deleteCartItem20"/> </after> <!-- Go to the shopping cart and check if the pager is missing--> - <actionGroup ref="StorefrontOpenCartPageActionGroup" stepKey="goToCartPage" /> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage" /> <actionGroup ref="AssertPagerTextIsNotVisibleActionGroup" stepKey="VerifyMissingPagerText" > <argument name="text" value="Items 1 to 20"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml index 9b536882dc64b..5df8338030efc 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutDataWhenChangeQtyTest.xml @@ -65,8 +65,7 @@ <seeInCurrentUrl url="{{CheckoutPage.url}}/#payment" stepKey="assertCheckoutPaymentUrl"/> <!--Go to cart page, update qty and proceed to checkout--> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <see userInput="Shopping Cart" stepKey="seeCartPageIsOpened"/> <fillField selector="{{CheckoutCartProductSection.qty($$createProduct.name$$)}}" userInput="2" stepKey="updateProductQty"/> <click selector="{{CheckoutCartProductSection.updateShoppingCartButton}}" stepKey="clickUpdateShoppingCart"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml index 391cfd254101a..9aea4ac79312a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontPersistentDataForGuestCustomerWithPhysicalQuoteTest.xml @@ -35,7 +35,7 @@ <argument name="product" value="$$createProduct$$"/> </actionGroup> <!-- 2. Go to Shopping Cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckoutCartIndexPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckoutCartIndexPage"/> <!-- 3. Open "Estimate Shipping and Tax" section and input data --> <actionGroup ref="StorefrontCartEstimateShippingAndTaxActionGroup" stepKey="fillEstimateShippingAndTaxSection"/> <actionGroup ref="StorefrontAssertShippingMethodPresentInCartActionGroup" stepKey="assertShippingMethodFlatRateIsPresentInCart"> @@ -78,7 +78,7 @@ <argument name="shippingMethod" value="Free Shipping"/> </actionGroup> <!-- 11. Go back to the shopping cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckoutCartIndexPage1"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckoutCartIndexPage1"/> <actionGroup ref="StorefrontAssertCartEstimateShippingAndTaxActionGroup" stepKey="assertCartEstimateShippingAndTaxAfterGoingBackToShoppingCart"> <argument name="customerData" value="Simple_UK_Customer_For_Shipment"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml index e6e5c4f1a9299..f666226233b6d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontProductNameMinicartOnCheckoutPageDifferentStoreViewsTest.xml @@ -69,7 +69,7 @@ <waitForPageLoad stepKey="waitForStoreView"/> <!--Check product name in Minicart--> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> <grabTextFrom selector="{{StorefrontMinicartSection.productName}}" stepKey="grabProductNameMinicart"/> <assertContains stepKey="assertProductNameMinicart"> <actualResult type="const">$grabProductNameMinicart</actualResult> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontShoppingCartPagerForOneItemPerPageAnd2ProductsTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontShoppingCartPagerForOneItemPerPageAnd2ProductsTest.xml index 2691dc2b9fd06..1bab01aac4641 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontShoppingCartPagerForOneItemPerPageAnd2ProductsTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontShoppingCartPagerForOneItemPerPageAnd2ProductsTest.xml @@ -37,7 +37,7 @@ <deleteData createDataKey="createSimpleProduct1" stepKey="deleteProduct1"/> <deleteData createDataKey="createSimpleProduct2" stepKey="deleteProduct2"/> </after> - <actionGroup ref="StorefrontOpenCartPageActionGroup" stepKey="goToCartPage" /> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage" /> <actionGroup ref="AssertToolbarTextIsVisibleInCartActionGroup" stepKey="VerifyPagerTextWithChangedConfiguration"> <argument name="text" value="Items 1 to 1 of 2 total"/> </actionGroup> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleProductQtyTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleProductQtyTest.xml index d166bfdac0ba4..f0c3a23a8d39c 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleProductQtyTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleProductQtyTest.xml @@ -36,8 +36,7 @@ </after> <!-- Go to the shopping cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnPageShoppingCart"/> - <waitForPageLoad stepKey="waitForCheckoutPageLoad1"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnPageShoppingCart"/> <!-- Change the product QTY --> <fillField selector="{{CheckoutCartProductSection.ProductQuantityByName($$createProduct.name$$)}}" userInput="{{quoteQty3Price123.qty}}" stepKey="changeCartQty"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleWithCustomOptionsProductQtyTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleWithCustomOptionsProductQtyTest.xml index 91a601dc6ef52..afb4ff03a4fc9 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleWithCustomOptionsProductQtyTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUpdateShoppingCartSimpleWithCustomOptionsProductQtyTest.xml @@ -43,8 +43,7 @@ </after> <!-- Go to the shopping cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnPageShoppingCart"/> - <waitForPageLoad stepKey="waitForCheckoutPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnPageShoppingCart"/> <!-- Change the product QTY --> <fillField selector="{{CheckoutCartProductSection.ProductQuantityByName($$createProduct.name$$)}}" userInput="{{quoteQty11Subtotal1320.qty}}" stepKey="changeCartQty"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml index 542c0ed6586e9..1828251e68635 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/ZeroSubtotalOrdersWithProcessingStatusTest.xml @@ -68,7 +68,7 @@ </actionGroup> <!--Proceed to shipment--> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickToOpenCard"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickToOpenCard"/> <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="clickToProceedToCheckout"/> <waitForPageLoad stepKey="waitForTheFormIsOpened"/> @@ -93,8 +93,8 @@ <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="filterOrderGridById"> <argument name="orderId" value="$grabOrderNumber"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForCreatedOrderPageOpened"/> + + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <!--Verify that Created order is in Processing status--> <see selector="{{AdminShipmentOrderInformationSection.orderStatus}}" userInput="Processing" stepKey="seeShipmentOrderStatus"/> diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php index 9fff4b622e596..7b7d956f457f0 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php @@ -255,6 +255,7 @@ private function getBillingComponent($paymentCode) ], 'filterBy' => [ 'target' => '${ $.provider }:${ $.parentScope }.country_id', + '__disableTmpl' => ['target' => false], 'field' => 'country_id', ], ], diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php index 350f9954208fa..3d69bc88bb73d 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -3,84 +3,90 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Checkout\Test\Unit\Model\Layout; +use Magento\Checkout\Model\Layout\DepersonalizePlugin; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\LayoutInterface; +use Magento\PageCache\Model\DepersonalizeChecker; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + /** - * Class DepersonalizePluginTest + * Unit tests for \Magento\Checkout\Model\Layout\DepersonalizePlugin class. */ -class DepersonalizePluginTest extends \PHPUnit\Framework\TestCase +class DepersonalizePluginTest extends TestCase { /** - * @var \Magento\Customer\Model\Layout\DepersonalizePluginTest + * @var DepersonalizePlugin */ - protected $plugin; + private $plugin; /** - * @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject + * @var LayoutInterface|MockObject */ - protected $layoutMock; + private $layoutMock; /** - * @var \Magento\Checkout\Model\Session|\PHPUnit_Framework_MockObject_MockObject + * @var CheckoutSession|MockObject */ - protected $checkoutSessionMock; + private $checkoutSessionMock; /** - * @var \Magento\PageCache\Model\DepersonalizeChecker|\PHPUnit_Framework_MockObject_MockObject + * @var DepersonalizeChecker|MockObject */ - protected $depersonalizeCheckerMock; + private $depersonalizeCheckerMock; /** - * SetUp + * @inheritdoc */ protected function setUp() { - $this->layoutMock = $this->createMock(\Magento\Framework\View\Layout::class); - $this->checkoutSessionMock = $this->createPartialMock( - \Magento\Framework\Session\Generic::class, - ['clearStorage', 'setData', 'getData'] - ); - $this->checkoutSessionMock = $this->createPartialMock(\Magento\Checkout\Model\Session::class, ['clearStorage']); - $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); - $this->cacheConfigMock = $this->createMock(\Magento\PageCache\Model\Config::class); - $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); + $this->layoutMock = $this->getMockForAbstractClass(LayoutInterface::class); + $this->checkoutSessionMock = $this->createPartialMock(CheckoutSession::class, ['clearStorage']); + $this->depersonalizeCheckerMock = $this->createMock(DepersonalizeChecker::class); - $this->plugin = new \Magento\Checkout\Model\Layout\DepersonalizePlugin( - $this->depersonalizeCheckerMock, - $this->checkoutSessionMock + $this->plugin = (new ObjectManagerHelper($this))->getObject( + DepersonalizePlugin::class, + [ + 'depersonalizeChecker' => $this->depersonalizeCheckerMock, + 'checkoutSession' => $this->checkoutSessionMock, + ] ); } /** - * Test method afterGenerateXml + * Test afterGenerateElements method when depersonalization is needed. + * + * @return void */ - public function testAfterGenerateXml() + public function testAfterGenerateElements(): void { - $expectedResult = $this->createMock(\Magento\Framework\View\Layout::class); - $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); $this->checkoutSessionMock ->expects($this->once()) ->method('clearStorage') - ->will($this->returnValue($expectedResult)); + ->willReturnSelf(); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $expectedResult); - $this->assertEquals($expectedResult, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } - public function testAfterGenerateXmlNoDepersonalize() + /** + * Test afterGenerateElements method when depersonalization is not needed. + * + * @return void + */ + public function testAfterGenerateElementsNoDepersonalize(): void { - $expectedResult = $this->createMock(\Magento\Framework\View\Layout::class); - $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); $this->checkoutSessionMock ->expects($this->never()) ->method('clearStorage') - ->will($this->returnValue($expectedResult)); + ->willReturnSelf(); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $expectedResult); - $this->assertEquals($expectedResult, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } } diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsPageUpdateTitleActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsPageUpdateTitleActionGroup.xml new file mode 100644 index 0000000000000..0ae610a59e480 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCmsPageUpdateTitleActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminCmsPageSetTitleActionGroup"> + <arguments> + <argument name="newTitle" type="string"/> + </arguments> + + <fillField stepKey="fillNewTitle" selector="{{CmsNewPagePageBasicFieldsSection.pageTitle}}" userInput="{{newTitle}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminEditCMSPageContentActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminEditCMSPageContentActionGroup.xml index b745e9705ed30..983e48359c3b4 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminEditCMSPageContentActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminEditCMSPageContentActionGroup.xml @@ -10,12 +10,15 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminEditCMSPageContentActionGroup"> <arguments> - <argument name="content" type="string" /> - <argument name="pageId" type="string" /> + <argument name="content" type="string"/> + <argument name="pageId" type="string"/> </arguments> - <amOnPage url="{{AdminCmsPageEditPage.url(pageId)}}" stepKey="navigateToEditCMSPage"/> + + <amOnPage url="{{AdminCmsPageEditPage.url(pageId)}}" stepKey="navigateToEditCMSPage"/> <waitForPageLoad stepKey="waitForCmsPageEditPage"/> - <conditionalClick selector="{{CmsNewPagePageActionsSection.contentSectionName}}" dependentSelector="{{CatalogWidgetSection.insertWidgetButton}}" visible="false" stepKey="clickShowHideEditorIfVisible"/> + <conditionalClick selector="{{CmsNewPagePageContentSection.header}}" dependentSelector="{{CmsNewPagePageContentSection.contentHeading}}" visible="false" stepKey="expandContentTab"/> + <waitForPageLoad time="30" stepKey="waitForPageLoadContentSection"/> + <conditionalClick selector="{{CmsNewPagePageActionsSection.showHideEditor}}" dependentSelector="{{CatalogWidgetSection.insertWidgetButton}}" visible="false" stepKey="clickNextShowHideEditorIfVisible"/> <waitForElementVisible selector="{{CmsNewPagePageContentSection.content}}" stepKey="waitForContentField"/> <fillField selector="{{CmsNewPagePageContentSection.content}}" userInput="{{content}}" stepKey="resetCMSPageToDefaultContent"/> <click selector="{{CmsNewPagePageActionsSection.saveAndContinueEdit}}" stepKey="clickSave"/> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminInsertRecentlyViewedWidgetActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminInsertRecentlyViewedWidgetActionGroup.xml index e8c66c68348fc..781cc32834462 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminInsertRecentlyViewedWidgetActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminInsertRecentlyViewedWidgetActionGroup.xml @@ -16,9 +16,10 @@ <argument name="buttonToShowSection1" type="string" defaultValue="1"/> <argument name="buttonToShowSection2" type="string" defaultValue="3" /> </arguments> - <click selector="{{CmsNewPagePageActionsSection.contentSectionName}}" stepKey="expandContent"/> - <waitForPageLoad time="50" stepKey="waitForPageLoadContentSection"/> - <conditionalClick selector="{{CmsNewPagePageActionsSection.showHideEditor}}" dependentSelector="{{CmsNewPagePageActionsSection.showHideEditor}}" visible="true" stepKey="clickNextShowHideEditorIfVisible"/> + + <conditionalClick selector="{{CmsNewPagePageActionsSection.contentSectionName}}" dependentSelector="{{CmsNewPagePageActionsSection.showHideEditor}}" visible="false" stepKey="expandContentSectionIfNotVisible"/> + <waitForPageLoad time="30" stepKey="waitForPageLoadContentSection"/> + <conditionalClick selector="{{CmsNewPagePageActionsSection.showHideEditor}}" dependentSelector="{{CatalogWidgetSection.insertWidgetButton}}" visible="false" stepKey="clickNextShowHideEditorIfVisible"/> <waitForElementVisible selector="{{CatalogWidgetSection.insertWidgetButton}}" stepKey="waitForInsertWidgetElement"/> <click selector="{{CatalogWidgetSection.insertWidgetButton}}" stepKey="clickInsertWidget"/> <waitForElementVisible selector="{{InsertWidgetSection.widgetTypeDropDown}}" time="30" stepKey="waitForWidgetTypeDropDownVisible"/> @@ -32,9 +33,9 @@ <click selector="{{WidgetSection.InsertWidget}}" stepKey="clickInsertWidgetToSave"/> <waitForPageLoad time="30" stepKey="waitForWidgetInsertPageLoad"/> <!-- Check that widget is inserted --> - <waitForElementVisible selector="#cms_page_form_content" stepKey="checkCMSContent" time="30"/> + <waitForElementVisible selector="{{CmsNewPagePageContentSection.content}}" stepKey="checkCMSContent" time="30"/> <click selector="{{CmsNewPagePageActionsSection.saveAndContinueEdit}}" stepKey="clickNextSave"/> <waitForPageLoad stepKey="waitForPageActionSave" time="30"/> <waitForElementVisible selector="*[data-ui-id='messages-message-success']" time="60" stepKey="waitForSaveSuccess"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsForCMSHomePageContentWYSIWYGDisabledActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsForCMSHomePageContentWYSIWYGDisabledActionGroup.xml index adaeb8c90ff0b..31aedde95d95b 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsForCMSHomePageContentWYSIWYGDisabledActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsForCMSHomePageContentWYSIWYGDisabledActionGroup.xml @@ -9,7 +9,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="ClearWidgetsForCMSHomePageContentWYSIWYGDisabledActionGroup"> - <amOnPage url="{{CmsPageEditPage.url('2')}}" stepKey="navigateToEditHomePagePage"/> + <amOnPage url="{{AdminCmsPageEditPage.url('2')}}" stepKey="navigateToEditHomePagePage"/> <waitForPageLoad stepKey="waitForCmsPageEditPage"/> <conditionalClick selector="{{CmsNewPagePageActionsSection.contentSectionName}}" dependentSelector="{{CatalogWidgetSection.insertWidgetButton}}" visible="false" stepKey="clickShowHideEditorIfVisible"/> <waitForElementVisible selector="{{CmsNewPagePageContentSection.content}}" stepKey="waitForContentField"/> diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsFromCMSContentActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsFromCMSContentActionGroup.xml index 98de51574aa4b..a50f674208d6a 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsFromCMSContentActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/ClearWidgetsFromCMSContentActionGroup.xml @@ -13,7 +13,7 @@ <description>Goes to the Admin CMS Page Edit page for the Page ID number 2. Clears the Widget and replaces it with Text. PLEASE NOTE: The Page ID/Text are Hardcoded.</description> </annotations> - <amOnPage url="{{CmsPageEditPage.url('2')}}" stepKey="navigateToEditHomePagePage"/> + <amOnPage url="{{AdminCmsPageEditPage.url('2')}}" stepKey="navigateToEditHomePagePage"/> <waitForPageLoad stepKey="waitEditHomePagePageToLoad"/> <click selector="{{CmsNewPagePageContentSection.header}}" stepKey="clickContentTab"/> <waitForElementNotVisible selector="{{CmsWYSIWYGSection.CheckIfTabExpand}}" stepKey="waitForTabExpand"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Page/AdminCmsPageEditPage.xml b/app/code/Magento/Cms/Test/Mftf/Page/AdminCmsPageEditPage.xml index 978b6d6a6d261..3c5461ff3a031 100644 --- a/app/code/Magento/Cms/Test/Mftf/Page/AdminCmsPageEditPage.xml +++ b/app/code/Magento/Cms/Test/Mftf/Page/AdminCmsPageEditPage.xml @@ -7,7 +7,7 @@ --> <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> - <page name="AdminCmsPageEditPage" area="admin" url="/cms/page/edit/page_id/{{id}}" parameterized="true" module="Magento_Cms"> + <page name="AdminCmsPageEditPage" area="admin" url="/cms/page/edit/page_id/{{pageId}}" parameterized="true" module="Magento_Cms"> <section name="CmsNewPagePageActionsSection"/> <section name="CmsNewPagePageBasicFieldsSection"/> <section name="CmsNewPagePageContentSection"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Page/CmsPageEditPage.xml b/app/code/Magento/Cms/Test/Mftf/Page/CmsPageEditPage.xml deleted file mode 100644 index 73db6b61343b1..0000000000000 --- a/app/code/Magento/Cms/Test/Mftf/Page/CmsPageEditPage.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - --> -<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> - <page name="CmsPageEditPage" area="admin" url="admin/cms_page/edit/page_id/{{var}}" parameterized="true" module="Magento_Cms"> - <section name="CmsNewPagePageActionsSection"/> - <section name="CmsNewPagePageBasicFieldsSection"/> - <section name="CmsNewPagePageContentSection"/> - <section name="CmsNewPagePageSeoSection"/> - </page> -</pages> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCheckCreateFolderEscapeAndEnterHandlesForWYSIWYGBlockTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCheckCreateFolderEscapeAndEnterHandlesForWYSIWYGBlockTest.xml index 0644542ccc0f3..aa29f33f90664 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCheckCreateFolderEscapeAndEnterHandlesForWYSIWYGBlockTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCheckCreateFolderEscapeAndEnterHandlesForWYSIWYGBlockTest.xml @@ -20,7 +20,7 @@ <before> <createData entity="_defaultBlock" stepKey="createPreReqBlock" /> - <actionGroup ref="LoginActionGroup" stepKey="login"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="login"/> <actionGroup ref="EnabledWYSIWYGActionGroup" stepKey="enableWYSIWYG"/> <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> </before> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateDisabledCmsBlockEntityAndAssignToCategoryTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateDisabledCmsBlockEntityAndAssignToCategoryTest.xml index 51fbbf8020545..2008278c53eeb 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateDisabledCmsBlockEntityAndAssignToCategoryTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateDisabledCmsBlockEntityAndAssignToCategoryTest.xml @@ -35,7 +35,7 @@ <actionGroup ref="AdminSetCMSBlockDisabledActionGroup" stepKey="disableBlock"/> <actionGroup ref="SaveCMSBlockActionGroup" stepKey="saveCMSBlock"/> - <actionGroup ref="AdminOpenCategoriesPageActionGroup" stepKey="openCategoriesPage"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openCategoriesPage"/> <actionGroup ref="AdminCategoriesExpandAllActionGroup" stepKey="expandAll"/> <actionGroup ref="AdminCategoriesOpenCategoryActionGroup" stepKey="openCategory"> <argument name="category" value="$$newDefaultCategory$$"/> @@ -46,6 +46,7 @@ <argument name="value" value="Static block only"/> </actionGroup> <actionGroup ref="AdminSaveCategoryActionGroup" stepKey="saveCategory"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <actionGroup ref="AssertStorefrontNoTextOnCategoryPageActionGroup" stepKey="assertBlockOnCategoryFrontPage"> <argument name="category" value="$$newDefaultCategory$$"/> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateEnabledCmsBlockEntityAndAssignToCategoryTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateEnabledCmsBlockEntityAndAssignToCategoryTest.xml index 5ccd8fa713cc0..a69b6156af849 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateEnabledCmsBlockEntityAndAssignToCategoryTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateEnabledCmsBlockEntityAndAssignToCategoryTest.xml @@ -29,7 +29,7 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <actionGroup ref="AdminOpenCategoriesPageActionGroup" stepKey="openCategoriesPage"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="openCategoriesPage"/> <actionGroup ref="AdminCategoriesExpandAllActionGroup" stepKey="expandAll"/> <actionGroup ref="AdminCategoriesOpenCategoryActionGroup" stepKey="openCategory"> <argument name="category" value="$$newDefaultCategory$$"/> @@ -40,6 +40,7 @@ <argument name="value" value="Static block only"/> </actionGroup> <actionGroup ref="AdminSaveCategoryActionGroup" stepKey="saveCategory"/> + <actionGroup ref="AssertAdminCategorySaveSuccessMessageActionGroup" stepKey="assertSuccessMessage"/> <actionGroup ref="AssertStorefrontTextOnCategoryPageActionGroup" stepKey="assertBlockOnCategoryFrontPage"> <argument name="category" value="$$newDefaultCategory$$"/> diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php index 4ffe4a6ad8774..e036e2a8ad200 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php @@ -11,7 +11,7 @@ use Magento\Framework\UrlInterface; use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponent\Processor; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use PHPUnit\Framework\MockObject\MockObject; /** * BlockActionsTest contains unit tests for \Magento\Cms\Ui\Component\Listing\Column\BlockActions class. @@ -96,7 +96,6 @@ public function testPrepareDataSource() 'edit' => [ 'href' => 'test/url/edit', 'label' => __('Edit'), - '__disableTmpl' => true, ], 'delete' => [ 'href' => 'test/url/delete', @@ -106,7 +105,6 @@ public function testPrepareDataSource() 'message' => __('Are you sure you want to delete a %1 record?', $title), ], 'post' => true, - '__disableTmpl' => true, ], ], ], diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php index 781d6d31246ca..e187534f46ad5 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php @@ -15,7 +15,7 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Framework\View\Element\UiComponent\Processor; use PHPUnit\Framework\TestCase; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use PHPUnit\Framework\MockObject\MockObject; /** * Test for Magento\Cms\Ui\Component\Listing\Column\PageActions class. @@ -176,7 +176,6 @@ public function configDataProvider():array 'edit' => [ 'href' => 'test/url/edit', 'label' => __('Edit'), - '__disableTmpl' => true, ], 'delete' => [ 'href' => 'test/url/delete', @@ -184,15 +183,12 @@ public function configDataProvider():array 'confirm' => [ 'title' => __('Delete %1', $title), 'message' => __('Are you sure you want to delete a %1 record?', $title), - '__disableTmpl' => true, ], 'post' => true, - '__disableTmpl' => true, ], 'preview' => [ 'href' => 'test/url/view', 'label' => __('View'), - '__disableTmpl' => true, 'target' => '_blank' ] ], diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php index 65940c5d7b4f9..6e9eef47281c0 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php @@ -70,7 +70,6 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Edit'), - '__disableTmpl' => true, ], 'delete' => [ 'href' => $this->urlBuilder->getUrl( @@ -85,7 +84,6 @@ public function prepareDataSource(array $dataSource) 'message' => __('Are you sure you want to delete a %1 record?', $title), ], 'post' => true, - '__disableTmpl' => true, ], ]; } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php index 0c6000bdbab84..7c04ce3e2e09e 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php @@ -87,7 +87,6 @@ public function prepareDataSource(array $dataSource) $item[$name]['edit'] = [ 'href' => $this->urlBuilder->getUrl($this->editUrl, ['page_id' => $item['page_id']]), 'label' => __('Edit'), - '__disableTmpl' => true, ]; $title = $this->getEscaper()->escapeHtml($item['title']); $item[$name]['delete'] = [ @@ -96,10 +95,8 @@ public function prepareDataSource(array $dataSource) 'confirm' => [ 'title' => __('Delete %1', $title), 'message' => __('Are you sure you want to delete a %1 record?', $title), - '__disableTmpl' => true, ], 'post' => true, - '__disableTmpl' => true, ]; } if (isset($item['identifier'])) { @@ -110,7 +107,6 @@ public function prepareDataSource(array $dataSource) isset($item['store_code']) ? $item['store_code'] : null ), 'label' => __('View'), - '__disableTmpl' => true, 'target' => '_blank' ]; } diff --git a/app/code/Magento/Config/App/Config/Source/RuntimeConfigSource.php b/app/code/Magento/Config/App/Config/Source/RuntimeConfigSource.php index b33c944c73477..7926708772a9f 100644 --- a/app/code/Magento/Config/App/Config/Source/RuntimeConfigSource.php +++ b/app/code/Magento/Config/App/Config/Source/RuntimeConfigSource.php @@ -8,9 +8,12 @@ use Magento\Framework\App\Config\ConfigSourceInterface; use Magento\Framework\App\Config\ScopeCodeResolver; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; use Magento\Config\Model\ResourceModel\Config\Data\CollectionFactory; use Magento\Framework\App\Config\Scope\Converter; +use Magento\Framework\DB\Adapter\TableNotFoundException; /** * Class for retrieving runtime configuration from database. @@ -34,20 +37,27 @@ class RuntimeConfigSource implements ConfigSourceInterface * @var ScopeCodeResolver */ private $scopeCodeResolver; + /** + * @var DeploymentConfig + */ + private $deploymentConfig; /** * @param CollectionFactory $collectionFactory * @param ScopeCodeResolver $scopeCodeResolver * @param Converter $converter + * @param DeploymentConfig|null $deploymentConfig */ public function __construct( CollectionFactory $collectionFactory, ScopeCodeResolver $scopeCodeResolver, - Converter $converter + Converter $converter, + ?DeploymentConfig $deploymentConfig = null ) { $this->collectionFactory = $collectionFactory; $this->converter = $converter; $this->scopeCodeResolver = $scopeCodeResolver; + $this->deploymentConfig = $deploymentConfig ?? ObjectManager::getInstance()->get(DeploymentConfig::class); } /** @@ -59,7 +69,7 @@ public function __construct( */ public function get($path = '') { - $data = new DataObject($this->loadConfig()); + $data = new DataObject($this->deploymentConfig->isDbAvailable() ? $this->loadConfig() : []); return $data->getData($path) ?: []; } @@ -75,8 +85,12 @@ private function loadConfig() { try { $collection = $this->collectionFactory->create(); + $collection->load(); } catch (\DomainException $e) { $collection = []; + } catch (TableNotFoundException $exception) { + // database is empty or not setup + $collection = []; } $config = []; foreach ($collection as $item) { diff --git a/app/code/Magento/Config/Model/Config/Source/Email/Template.php b/app/code/Magento/Config/Model/Config/Source/Email/Template.php index e4f1ae65bcacd..ac168f16ca182 100644 --- a/app/code/Magento/Config/Model/Config/Source/Email/Template.php +++ b/app/code/Magento/Config/Model/Config/Source/Email/Template.php @@ -64,12 +64,6 @@ public function toOptionArray() $templateLabel = $this->_emailConfig->getTemplateLabel($templateId); $templateLabel = __('%1 (Default)', $templateLabel); array_unshift($options, ['value' => $templateId, 'label' => $templateLabel]); - array_walk( - $options, - function (&$item) { - $item['__disableTmpl'] = true; - } - ); return $options; } } diff --git a/app/code/Magento/Config/Test/Mftf/Test/CheckingCountryDropDownWithOneAllowedCountryTest.xml b/app/code/Magento/Config/Test/Mftf/Test/CheckingCountryDropDownWithOneAllowedCountryTest.xml index 9e05f4819cd73..5327979154389 100644 --- a/app/code/Magento/Config/Test/Mftf/Test/CheckingCountryDropDownWithOneAllowedCountryTest.xml +++ b/app/code/Magento/Config/Test/Mftf/Test/CheckingCountryDropDownWithOneAllowedCountryTest.xml @@ -35,8 +35,14 @@ <!--Flush Magento Cache--> <magentoCLI stepKey="flushCache" command="cache:flush"/> <!--Create a customer account from Storefront--> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="createAnAccount"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <click selector="{{CheckoutPaymentSection.addressBook}}" stepKey="goToAddressBook"/> <click selector="{{StorefrontCustomerAddressSection.country}}" stepKey="clickToExpandCountryDropDown"/> diff --git a/app/code/Magento/Config/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php b/app/code/Magento/Config/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php index ae6ee8a028868..d880d93d78da3 100644 --- a/app/code/Magento/Config/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php +++ b/app/code/Magento/Config/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php @@ -5,41 +5,46 @@ */ namespace Magento\Config\Test\Unit\App\Config\Source; +use ArrayIterator; use Magento\Config\App\Config\Source\RuntimeConfigSource; +use Magento\Config\Model\ResourceModel\Config\Data\Collection; use Magento\Config\Model\ResourceModel\Config\Data\CollectionFactory; use Magento\Framework\App\Config\Scope\Converter; use Magento\Framework\App\Config\ScopeCodeResolver; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\Config\Value; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\DB\Adapter\TableNotFoundException; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** * Test Class for retrieving runtime configuration from database. - * @package Magento\Config\Test\Unit\App\Config\Source */ -class RuntimeConfigSourceTest extends \PHPUnit\Framework\TestCase +class RuntimeConfigSourceTest extends TestCase { /** - * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + * @var CollectionFactory|MockObject */ private $collectionFactory; /** - * @var ScopeCodeResolver|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeCodeResolver|MockObject */ private $scopeCodeResolver; /** - * @var Converter|\PHPUnit_Framework_MockObject_MockObject + * @var Converter|MockObject */ private $converter; /** - * @var Value|\PHPUnit_Framework_MockObject_MockObject + * @var Value|MockObject */ private $configItem; /** - * @var Value|\PHPUnit_Framework_MockObject_MockObject + * @var Value|MockObject */ private $configItemTwo; @@ -47,6 +52,10 @@ class RuntimeConfigSourceTest extends \PHPUnit\Framework\TestCase * @var RuntimeConfigSource */ private $configSource; + /** + * @var DeploymentConfig|MockObject + */ + private $deploymentConfig; public function setUp() { @@ -68,20 +77,29 @@ public function setUp() ->disableOriginalConstructor() ->setMethods(['getScope', 'getPath', 'getValue', 'getScopeId']) ->getMock(); + $this->deploymentConfig = $this->createPartialMock(DeploymentConfig::class, ['isDbAvailable']); $this->configSource = new RuntimeConfigSource( $this->collectionFactory, $this->scopeCodeResolver, - $this->converter + $this->converter, + $this->deploymentConfig ); } public function testGet() { + $this->deploymentConfig->method('isDbAvailable') + ->willReturn(true); + $collection = $this->createPartialMock(Collection::class, ['load', 'getIterator']); + $collection->method('load') + ->willReturn($collection); + $collection->method('getIterator') + ->willReturn(new ArrayIterator([$this->configItem, $this->configItemTwo])); $scope = 'websites'; $scopeCode = 'myWebsites'; $this->collectionFactory->expects($this->once()) ->method('create') - ->willReturn([$this->configItem, $this->configItemTwo]); + ->willReturn($collection); $this->configItem->expects($this->exactly(2)) ->method('getScope') ->willReturn(ScopeConfigInterface::SCOPE_TYPE_DEFAULT); @@ -133,4 +151,22 @@ public function testGet() $this->configSource->get() ); } + + public function testGetWhenDbIsNotAvailable() + { + $this->deploymentConfig->method('isDbAvailable')->willReturn(false); + $this->assertEquals([], $this->configSource->get()); + } + + public function testGetWhenDbIsEmpty() + { + $this->deploymentConfig->method('isDbAvailable') + ->willReturn(true); + $collection = $this->createPartialMock(Collection::class, ['load']); + $collection->method('load') + ->willThrowException($this->createMock(TableNotFoundException::class)); + $this->collectionFactory->method('create') + ->willReturn($collection); + $this->assertEquals([], $this->configSource->get()); + } } diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php index 9fabe6fef0c8e..1fc730ccef30e 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php @@ -6,6 +6,8 @@ namespace Magento\Config\Test\Unit\Model\Config\Source\Email; +use PHPUnit\Framework\MockObject\MockObject; + /** * Test class for Template. */ @@ -17,12 +19,12 @@ class TemplateTest extends \PHPUnit\Framework\TestCase protected $_model; /** - * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Registry|MockObject */ protected $_coreRegistry; /** - * @var \Magento\Email\Model\Template\Config|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Email\Model\Template\Config|MockObject */ protected $_emailConfig; @@ -82,17 +84,14 @@ public function testToOptionArray() [ 'value' => 'template_new', 'label' => 'Template New (Default)', - '__disableTmpl' => true ], [ 'value' => 'template_one', 'label' => 'Template One', - '__disableTmpl' => true ], [ 'value' => 'template_two', 'label' => 'Template Two', - '__disableTmpl' => true ], ]; $this->_model->setPath('template/new'); diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php index b9fcf307b613f..e64a92a8bd6f4 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php @@ -12,6 +12,7 @@ /** * Product variations matrix block + * All disableTmpl flag are required here for configurable products * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php index 54b6e42ff7678..8bc7f05b49e30 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php +++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php @@ -5,15 +5,17 @@ */ namespace Magento\ConfigurableProduct\Model\Plugin; -use Magento\Catalog\Model\ProductFactory; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Framework\Exception\InputException; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Framework\Exception\CouldNotSaveException; use Magento\ConfigurableProduct\Api\Data\OptionInterface; use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\Framework\Exception\NoSuchEntityException; +/** + * Plugin to validate product links of configurable product and reset configurable attributes + */ class ProductRepositorySave { /** @@ -22,46 +24,45 @@ class ProductRepositorySave private $productAttributeRepository; /** - * @var ProductFactory + * @var ProductRepositoryInterface */ - private $productFactory; + private $productRepository; /** * @param ProductAttributeRepositoryInterface $productAttributeRepository - * @param ProductFactory $productFactory + * @param ProductRepositoryInterface $productRepository */ public function __construct( ProductAttributeRepositoryInterface $productAttributeRepository, - ProductFactory $productFactory + ProductRepositoryInterface $productRepository ) { $this->productAttributeRepository = $productAttributeRepository; - $this->productFactory = $productFactory; + $this->productRepository = $productRepository; } /** - * Validate product links and reset configurable attributes to configurable product + * Validate product links of configurable product * * @param ProductRepositoryInterface $subject - * @param ProductInterface $result * @param ProductInterface $product * @param bool $saveOptions - * @return ProductInterface - * @throws CouldNotSaveException + * @return array * @throws InputException + * @throws NoSuchEntityException * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterSave( + public function beforeSave( ProductRepositoryInterface $subject, - ProductInterface $result, ProductInterface $product, $saveOptions = false ) { + $result[] = $product; if ($product->getTypeId() !== Configurable::TYPE_CODE) { return $result; } - $extensionAttributes = $result->getExtensionAttributes(); + $extensionAttributes = $product->getExtensionAttributes(); if ($extensionAttributes === null) { return $result; } @@ -81,23 +82,49 @@ public function afterSave( $attributeCodes[] = $attributeCode; } $this->validateProductLinks($attributeCodes, $configurableLinks); + + return $result; + } + + /** + * Reset configurable attributes to configurable product + * + * @param ProductRepositoryInterface $subject + * @param ProductInterface $result + * @param ProductInterface $product + * @param bool $saveOptions + * @return ProductInterface + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterSave( + ProductRepositoryInterface $subject, + ProductInterface $result, + ProductInterface $product, + $saveOptions = false + ) { + if ($product->getTypeId() !== Configurable::TYPE_CODE) { + return $result; + } $result->getTypeInstance()->resetConfigurableAttributes($product); return $result; } /** + * Validate product links + * * @param array $attributeCodes * @param array $linkIds - * @return $this + * @return void * @throws InputException + * @throws NoSuchEntityException */ private function validateProductLinks(array $attributeCodes, array $linkIds) { $valueMap = []; - foreach ($linkIds as $productId) { - $variation = $this->productFactory->create()->load($productId); + $variation = $this->productRepository->getById($productId); $valueKey = ''; foreach ($attributeCodes as $attributeCode) { if (!$variation->getData($attributeCode)) { diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAssertNoticeThatExistingSkuAutomaticallyChangedWhenSavingProductWithSameSkuTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAssertNoticeThatExistingSkuAutomaticallyChangedWhenSavingProductWithSameSkuTest.xml index d58e7cfab1350..6e26d73f3a36f 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAssertNoticeThatExistingSkuAutomaticallyChangedWhenSavingProductWithSameSkuTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAssertNoticeThatExistingSkuAutomaticallyChangedWhenSavingProductWithSameSkuTest.xml @@ -27,8 +27,8 @@ </actionGroup> <!-- Delete product attribute --> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> - <argument name="ProductAttribute" value="colorProductAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> + <argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}"/> </actionGroup> <!-- Log out --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml index 78cbca2d4c099..e5456429373e1 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml @@ -27,8 +27,8 @@ </actionGroup> <!-- Delete product attribute --> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> - <argument name="ProductAttribute" value="colorProductAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> + <argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}"/> </actionGroup> <!-- Log out --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithCreatingCategoryAndAttributeTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithCreatingCategoryAndAttributeTest.xml index 3913139c9b7e6..32117fdfe4366 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithCreatingCategoryAndAttributeTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithCreatingCategoryAndAttributeTest.xml @@ -36,8 +36,8 @@ </actionGroup> <!-- Delete product attribute --> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> - <argument name="ProductAttribute" value="colorProductAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> + <argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}"/> </actionGroup> <!-- Delete attribute set --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsAssignedToCategoryTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsAssignedToCategoryTest.xml index 868690e19f6ba..f2a8e78523758 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsAssignedToCategoryTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsAssignedToCategoryTest.xml @@ -39,8 +39,8 @@ </actionGroup> <!-- Delete product attribute --> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> - <argument name="ProductAttribute" value="colorProductAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> + <argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}"/> </actionGroup> <!-- Delete attribute set --> @@ -131,8 +131,7 @@ <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" stepKey="waitForSuccessMessage"/> <!-- Assert configurable product in cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnShoppingCartPage"/> <actionGroup ref="StorefrontCheckCartConfigurableProductActionGroup" stepKey="storefrontCheckCartConfigurableProductActionGroup"> <argument name="product" value="ApiConfigurableProduct"/> <argument name="optionProduct" value="colorConfigurableProductAttribute1"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsWithoutAssignedToCategoryTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsWithoutAssignedToCategoryTest.xml index 9335f49c9bc2e..273e37089973b 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsWithoutAssignedToCategoryTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithTwoOptionsWithoutAssignedToCategoryTest.xml @@ -35,8 +35,8 @@ </actionGroup> <!-- Delete product attribute --> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> - <argument name="ProductAttribute" value="colorProductAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> + <argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}"/> </actionGroup> <!-- Delete attribute set --> @@ -113,8 +113,7 @@ <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" stepKey="waitForSuccessMessage"/> <!-- Assert configurable product in cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnShoppingCartPage"/> <actionGroup ref="StorefrontCheckCartConfigurableProductActionGroup" stepKey="storefrontCheckCartConfigurableProductActionGroup"> <argument name="product" value="ApiConfigurableProduct"/> <argument name="optionProduct" value="colorConfigurableProductAttribute1"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml index 85c852d09e916..e4a9755adcef4 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml @@ -62,7 +62,7 @@ </createData> <updateData entity="ApiSimpleProductUpdateDescription" stepKey="updateConfigProduct" createDataKey="createConfigProduct"/> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> </before> <after> <!-- @TODO: Uncomment once MQE-679 is fixed --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoErrorForMiniCartItemEditTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoErrorForMiniCartItemEditTest.xml index c2ac4dde21c35..10d8aeb875742 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoErrorForMiniCartItemEditTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/NoErrorForMiniCartItemEditTest.xml @@ -60,7 +60,7 @@ <waitForPageLoad stepKey="waitForMiniCart"/> <!-- Edit Item in Cart --> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="openMiniCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="openMiniCart"/> <click selector="{{StorefrontMinicartSection.editMiniCartItem}}" stepKey="clickEditCartItem"/> <!-- Check if Product Configuration is still selected --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml index 355c4fa049f01..a8856288b422a 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ProductsQtyReturnAfterOrderCancelTest.xml @@ -70,8 +70,7 @@ <argument name="orderId" value="$grabOrderNumber"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> <waitForPageLoad stepKey="waitForNewInvoicePageLoad"/> <fillField selector="{{AdminInvoiceItemsSection.qtyToInvoiceColumn}}" userInput="1" stepKey="ChangeQtyToInvoice"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml index e983559fb6bcf..bbd5dbd8068f7 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml @@ -65,8 +65,7 @@ <see selector="{{StorefrontProductPageSection.messagesBlock}}" userInput="You added {{BaseConfigurableProduct.name}} to your shopping cart." stepKey="seeSuccessMessage"/> <!--Check item in cart--> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <seeElement selector="{{CheckoutCartProductSection.ProductLinkByName(BaseConfigurableProduct.name)}}" stepKey="seeProductInCart"/> <see selector="{{CheckoutCartProductSection.ProductOptionByNameAndAttribute(BaseConfigurableProduct.name, colorProductAttribute.default_label)}}" userInput="{{colorProductAttribute2.name}}" stepKey="seeSelectedOption"/> <see selector="{{CheckoutCartProductSection.ProductOptionByNameAndAttribute(BaseConfigurableProduct.name, ProductOptionFile.title)}}" userInput="{{MagentoLogo.file}}" stepKey="seeCorrectOptionFile"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithSeveralAttributesPrependMediaTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithSeveralAttributesPrependMediaTest.xml index a50d1e32d3614..3e74edfb68074 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithSeveralAttributesPrependMediaTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithSeveralAttributesPrependMediaTest.xml @@ -141,7 +141,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveConfigurableProductVariationOption2Option2"/> <!-- Reindex invalidated indices after product attribute has been created --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndicesAfterCreateAttributes"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndicesAfterCreateAttributes"/> </before> <after> @@ -160,7 +160,7 @@ <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearProductAttributeGridFilters"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> <!-- Reindex invalidated indices after product attribute has been created --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndicesAfterDeleteAttributes"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndicesAfterDeleteAttributes"/> </after> <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openConfigurableProductPage"> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml index be81b64c7ed25..c76d49a76d947 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontGalleryConfigurableProductWithVisualSwatchAttributePrependMediaTest.xml @@ -106,7 +106,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveConfigurableProductVariationOption3"/> <!-- Reindex invalidated indices after product attribute has been created --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndicesAfterCreateAttributes"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndicesAfterCreateAttributes"/> </before> <after> @@ -122,7 +122,7 @@ <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearProductAttributeGridFilters"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> <!-- Reindex invalidated indices after product attribute has been created --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndicesAfterDeleteAttributes"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndicesAfterDeleteAttributes"/> </after> <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openConfigurableProductPage"> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml index 6126338461fdd..801dfdb8540e8 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml @@ -36,12 +36,12 @@ <actionGroup ref="ResetProductGridToDefaultViewActionGroup" stepKey="resetGridToDefaultKeywordSearch"/> <!--Delete product attributes--> <comment userInput="Delete product attributes" stepKey="deleteCommentAttributes"/> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> - <argument name="ProductAttribute" value="colorProductAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteProductAttribute"> + <argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}"/> </actionGroup> <click selector="{{AdminProductAttributeGridSection.ResetFilter}}" stepKey="resetFiltersOnGridFirst"/> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteProductSecondAttribute"> - <argument name="ProductAttribute" value="productAttributeColor"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteProductSecondAttribute"> + <argument name="productAttributeLabel" value="{{productAttributeColor.default_label}}"/> </actionGroup> <click selector="{{AdminProductAttributeGridSection.ResetFilter}}" stepKey="resetFiltersOnGridSecond"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php index c385934352ab8..5a238ceca20a5 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php @@ -8,6 +8,7 @@ use Magento\ConfigurableProduct\Model\LinkManagement; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use PHPUnit\Framework\MockObject\MockObject; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -15,12 +16,12 @@ class LinkManagementTest extends \PHPUnit\Framework\TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $productRepository; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $productFactory; @@ -30,7 +31,7 @@ class LinkManagementTest extends \PHPUnit\Framework\TestCase protected $objectManagerHelper; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $configurableType; @@ -40,7 +41,7 @@ class LinkManagementTest extends \PHPUnit\Framework\TestCase protected $object; /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\DataObjectHelper + * @var MockObject|\Magento\Framework\Api\DataObjectHelper */ protected $dataObjectHelperMock; @@ -149,7 +150,7 @@ public function testAddChild() ->disableOriginalConstructor() ->setMethods(['getId', 'getData']) ->getMock(); - $extensionAttributesMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductExtension::class) + $extensionAttributesMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductExtensionInterface::class) ->disableOriginalConstructor() ->setMethods( [ @@ -158,11 +159,11 @@ public function testAddChild() 'setConfigurableProductLinks' ] ) - ->getMock(); - $optionMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Api\Data\Option::class) + ->getMockForAbstractClass(); + $optionMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Api\Data\OptionInterface::class) ->disableOriginalConstructor() ->setMethods(['getProductAttribute', 'getPosition', 'getAttributeId']) - ->getMock(); + ->getMockForAbstractClass(); $productAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) ->disableOriginalConstructor() ->setMethods(['getAttributeCode']) diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php index 1c3e421ae924f..ea8bb065a7786 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php @@ -9,30 +9,26 @@ use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\ProductFactory; use Magento\ConfigurableProduct\Api\Data\OptionInterface; use Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; use Magento\ConfigurableProduct\Test\Unit\Model\Product\ProductExtensionAttributes; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** - * Class ProductRepositorySaveTest + * Test for ProductRepositorySave plugin + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class ProductRepositorySaveTest extends \PHPUnit\Framework\TestCase +class ProductRepositorySaveTest extends TestCase { /** * @var ProductAttributeRepositoryInterface|MockObject */ private $productAttributeRepository; - /** - * @var ProductFactory|MockObject - */ - private $productFactory; - /** * @var Product|MockObject */ @@ -68,15 +64,13 @@ class ProductRepositorySaveTest extends \PHPUnit\Framework\TestCase */ private $plugin; + /** + * @inheritdoc + */ protected function setUp() { $this->productAttributeRepository = $this->getMockForAbstractClass(ProductAttributeRepositoryInterface::class); - $this->productFactory = $this->getMockBuilder(ProductFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->product = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() ->setMethods(['getTypeId', 'getExtensionAttributes']) @@ -102,12 +96,15 @@ protected function setUp() ProductRepositorySave::class, [ 'productAttributeRepository' => $this->productAttributeRepository, - 'productFactory' => $this->productFactory + 'productRepository' => $this->productRepository ] ); } - public function testAfterSaveWhenProductIsSimple() + /** + * Validating the result after saving a configurable product + */ + public function testBeforeSaveWhenProductIsSimple() { $this->product->expects(static::once()) ->method('getTypeId') @@ -116,18 +113,21 @@ public function testAfterSaveWhenProductIsSimple() ->method('getExtensionAttributes'); $this->assertEquals( - $this->result, - $this->plugin->afterSave($this->productRepository, $this->result, $this->product) + $this->product, + $this->plugin->beforeSave($this->productRepository, $this->product)[0] ); } - public function testAfterSaveWithoutOptions() + /** + * Test saving a configurable product without attribute options + */ + public function testBeforeSaveWithoutOptions() { $this->product->expects(static::once()) ->method('getTypeId') ->willReturn(Configurable::TYPE_CODE); - $this->result->expects(static::once()) + $this->product->expects(static::once()) ->method('getExtensionAttributes') ->willReturn($this->extensionAttributes); @@ -142,23 +142,25 @@ public function testAfterSaveWithoutOptions() ->method('get'); $this->assertEquals( - $this->result, - $this->plugin->afterSave($this->productRepository, $this->result, $this->product) + $this->product, + $this->plugin->beforeSave($this->productRepository, $this->product)[0] ); } /** + * Test saving a configurable product with same set of attribute values + * * @expectedException \Magento\Framework\Exception\InputException * @expectedExceptionMessage Products "5" and "4" have the same set of attribute values. */ - public function testAfterSaveWithLinks() + public function testBeforeSaveWithLinks() { $links = [4, 5]; $this->product->expects(static::once()) ->method('getTypeId') ->willReturn(Configurable::TYPE_CODE); - $this->result->expects(static::once()) + $this->product->expects(static::once()) ->method('getExtensionAttributes') ->willReturn($this->extensionAttributes); $this->extensionAttributes->expects(static::once()) @@ -173,27 +175,26 @@ public function testAfterSaveWithLinks() $product = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() - ->setMethods(['load', 'getData', '__wakeup']) + ->setMethods(['getData', '__wakeup']) ->getMock(); - $this->productFactory->expects(static::exactly(2)) - ->method('create') + $this->productRepository->expects(static::exactly(2)) + ->method('getById') ->willReturn($product); - $product->expects(static::exactly(2)) - ->method('load') - ->willReturnSelf(); $product->expects(static::never()) ->method('getData'); - $this->plugin->afterSave($this->productRepository, $this->result, $this->product); + $this->plugin->beforeSave($this->productRepository, $this->product); } /** + * Test saving a configurable product with missing attribute + * * @expectedException \Magento\Framework\Exception\InputException * @expectedExceptionMessage Product with id "4" does not contain required attribute "color". */ - public function testAfterSaveWithLinksWithMissingAttribute() + public function testBeforeSaveWithLinksWithMissingAttribute() { $simpleProductId = 4; $links = [$simpleProductId, 5]; @@ -208,7 +209,7 @@ public function testAfterSaveWithLinksWithMissingAttribute() ->method('getTypeId') ->willReturn(Configurable::TYPE_CODE); - $this->result->expects(static::once()) + $this->product->expects(static::once()) ->method('getExtensionAttributes') ->willReturn($this->extensionAttributes); $this->extensionAttributes->expects(static::once()) @@ -228,29 +229,28 @@ public function testAfterSaveWithLinksWithMissingAttribute() $product = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() - ->setMethods(['load', 'getData', '__wakeup']) + ->setMethods(['getData', '__wakeup']) ->getMock(); - $this->productFactory->expects(static::once()) - ->method('create') + $this->productRepository->expects(static::once()) + ->method('getById') ->willReturn($product); - $product->expects(static::once()) - ->method('load') - ->with($simpleProductId) - ->willReturnSelf(); + $product->expects(static::once()) ->method('getData') ->with($attributeCode) ->willReturn(false); - $this->plugin->afterSave($this->productRepository, $this->result, $this->product); + $this->plugin->beforeSave($this->productRepository, $this->product); } /** + * Test saving a configurable product with duplicate attributes + * * @expectedException \Magento\Framework\Exception\InputException * @expectedExceptionMessage Products "5" and "4" have the same set of attribute values. */ - public function testAfterSaveWithLinksWithDuplicateAttributes() + public function testBeforeSaveWithLinksWithDuplicateAttributes() { $links = [4, 5]; $attributeCode = 'color'; @@ -264,7 +264,7 @@ public function testAfterSaveWithLinksWithDuplicateAttributes() ->method('getTypeId') ->willReturn(Configurable::TYPE_CODE); - $this->result->expects(static::once()) + $this->product->expects(static::once()) ->method('getExtensionAttributes') ->willReturn($this->extensionAttributes); $this->extensionAttributes->expects(static::once()) @@ -284,20 +284,18 @@ public function testAfterSaveWithLinksWithDuplicateAttributes() $product = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() - ->setMethods(['load', 'getData', '__wakeup']) + ->setMethods(['getData', '__wakeup']) ->getMock(); - $this->productFactory->expects(static::exactly(2)) - ->method('create') + $this->productRepository->expects(static::exactly(2)) + ->method('getById') ->willReturn($product); - $product->expects(static::exactly(2)) - ->method('load') - ->willReturnSelf(); + $product->expects(static::exactly(4)) ->method('getData') ->with($attributeCode) ->willReturn($attributeId); - $this->plugin->afterSave($this->productRepository, $this->result, $this->product); + $this->plugin->beforeSave($this->productRepository, $this->product); } } diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php index 67773f019be8c..82bc6faac6bcc 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableAttributeSetHandler.php @@ -33,7 +33,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -41,7 +41,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -204,6 +204,7 @@ protected function getNewAttributeSet() 'visible' => 'ns = ${ $.ns }, index = affectedAttributeSetNew:checked', 'disabled' => '!ns = ${ $.ns }, index = affectedAttributeSetNew:checked', + '__disableTmpl' => ['disabled' => false, 'visible' => false], ] ], ], @@ -243,6 +244,7 @@ protected function getExistingAttributeSet($meta) 'visible' => 'ns = ${ $.ns }, index = affectedAttributeSetExisting:checked', 'disabled' => '!ns = ${ $.ns }, index = affectedAttributeSetExisting:checked', + '__disableTmpl' => ['disabled' => false, 'value' => false, 'visible' => false], ], ], ], diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php index 16119dcb5c866..4e11c49f10162 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePanel.php @@ -167,6 +167,7 @@ public function modifyMeta(array $meta) 'imports' => [ 'visible' => '!ns = ${ $.ns }, index = ' . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', + '__disableTmpl' => ['visible' => false], ], ], ], @@ -185,6 +186,7 @@ public function modifyMeta(array $meta) 'imports' => [ 'visible' => 'ns = ${ $.ns }, index = ' . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', + '__disableTmpl' => ['visible' => false], ], ], ], @@ -284,6 +286,7 @@ protected function getButtonSet() ), 'template' => 'ui/form/components/complex', 'createConfigurableButton' => 'ns = ${ $.ns }, index = create_configurable_products_button', + '__disableTmpl' => ['createConfigurableButton' => false], ], ], ], @@ -314,6 +317,7 @@ protected function getButtonSet() 'imports' => [ 'visible' => 'ns = ${ $.ns }, index = ' . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isShowAddProductButton', + '__disableTmpl' => ['visible' => false], ], ], ], @@ -392,6 +396,11 @@ protected function getGrid() 'insertDataFromGrid' => '${$.provider}:${$.dataProviderFromGrid}', 'insertDataFromWizard' => '${$.provider}:${$.dataProviderFromWizard}', 'changeDataFromGrid' => '${$.provider}:${$.dataProviderChangeFromGrid}', + '__disableTmpl' => [ + 'insertDataFromGrid' => false, + 'insertDataFromWizard' => false, + 'changeDataFromGrid' => false + ], ], 'sortOrder' => 20, 'columnsHeader' => false, @@ -445,6 +454,11 @@ protected function getRows() 'thumbnailUrl' => '${$.provider}:${$.parentScope}.thumbnail_image', 'thumbnail' => '${$.provider}:${$.parentScope}.thumbnail', 'smallImage' => '${$.provider}:${$.parentScope}.small_image', + '__disableTmpl' => [ + 'thumbnailUrl' => false, + 'thumbnail' => false, + 'smallImage' => false + ], ], 'uploaderConfig' => [ 'url' => $this->urlBuilder->getUrl( @@ -482,7 +496,10 @@ protected function getRows() 'price', __('Price'), [ - 'imports' => ['addbefore' => '${$.provider}:${$.parentScope}.price_currency'], + 'imports' => [ + 'addbefore' => '${$.provider}:${$.parentScope}.price_currency', + '__disableTmpl' => ['addbefore' => false], + ], 'validation' => ['validate-zero-or-greater' => true] ], ['dataScope' => 'price_string'] @@ -564,7 +581,8 @@ protected function getColumn( 'fit' => true, 'visibleIfCanEdit' => true, 'imports' => [ - 'visible' => '${$.provider}:${$.parentScope}.canEdit' + 'visible' => '${$.provider}:${$.parentScope}.canEdit', + '__disableTmpl' => ['visible' => false], ], ]; $fieldText['arguments']['data']['config'] = [ @@ -576,7 +594,8 @@ protected function getColumn( 'visibleIfCanEdit' => false, 'labelVisible' => false, 'imports' => [ - 'visible' => '!${$.provider}:${$.parentScope}.canEdit' + 'visible' => '!${$.provider}:${$.parentScope}.canEdit', + '__disableTmpl' => ['visible' => false], ], ]; $fieldEdit['arguments']['data']['config'] = array_replace_recursive( diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php index d3129a09d0056..241798a5a0fb2 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php @@ -37,7 +37,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -45,7 +45,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -82,6 +82,7 @@ public function modifyMeta(array $meta) 'imports' => [ 'visible' => 'ns = ${ $.ns }, index = ' . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', + '__disableTmpl' => ['visible' => false], ] ]; $config = $visibilityConfig; diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php index 636d832842f92..d791db2ff78b9 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php @@ -40,7 +40,7 @@ public function __construct(LocatorInterface $locator, ArrayManager $arrayManage } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -48,7 +48,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -92,7 +92,8 @@ private function addPriceTypeWarning(array $meta) ), 'imports' => [ 'updateVisibility' => 'ns = ${ $.ns }, index = ' - . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty' + . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', + '__disableTmpl' => ['updateVisibility' => false], ] ] ); @@ -128,6 +129,7 @@ private function modifyPriceTypeFields(array $meta) 'imports' => [ 'updateOptions' => 'ns = ${ $.ns }, index = ' . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', + '__disableTmpl' => ['updateOptions' => false], ], ] ); diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index ec69baeb92cb9..7815408321ed4 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -215,7 +215,6 @@ public function getConfigurableAttributesData() 'code' => $attribute['code'], 'label' => $attribute['label'], 'position' => $attribute['position'], - '__disableTmpl' => true ]; foreach ($attribute['chosen'] as $chosenOption) { @@ -266,7 +265,6 @@ protected function prepareVariations() 'id' => $attribute->getAttributeId(), 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], - '__disableTmpl' => true ]; $options = $attribute->usesSource() ? $attribute->getSource()->getAllOptions() : []; foreach ($options as $option) { @@ -277,7 +275,6 @@ protected function prepareVariations() 'id' => $option['value'], 'label' => $option['label'], 'value' => $option['value'], - '__disableTmpl' => true ]; } } @@ -289,7 +286,6 @@ protected function prepareVariations() 'id' => $optionId, 'label' => $variation[$attribute->getId()]['label'], 'value' => $optionId, - '__disableTmpl' => true ]; $variationOptions[] = $variationOption; $attributes[$attribute->getAttributeId()]['chosen'][$optionId] = $variationOption; @@ -315,7 +311,6 @@ protected function prepareVariations() 'newProduct' => 0, 'attributes' => $this->getTextAttributes($variationOptions), 'thumbnail_image' => $this->imageHelper->init($product, 'product_thumbnail_image')->getUrl(), - '__disableTmpl' => true ]; $productIds[] = $product->getId(); } diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/StockData.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/StockData.php index db51e7eebefc4..32b92a197f7d9 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/StockData.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/StockData.php @@ -69,6 +69,7 @@ public function modifyMeta(array $meta) 'imports' => [ 'disabled' => '!ns = ${ $.ns }, index = ' . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', + '__disableTmpl' => ['disabled' => false], ], ]; diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCurrencyConverterAPIConfigurationTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCurrencyConverterAPIConfigurationTest.xml index 5d6d05ebfead4..f7e6e05347345 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCurrencyConverterAPIConfigurationTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminCurrencyConverterAPIConfigurationTest.xml @@ -47,14 +47,14 @@ <actionGroup ref="AdminImportCurrencyRatesActionGroup" stepKey="importCurrencyRates"> <argument name="rateService" value="Currency Converter API"/> </actionGroup> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput='Click "Save" to apply the rates we found.' stepKey="seeImportMessage"/> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput="We can't retrieve a rate from https://free.currconv.com for CHE." stepKey="seeWarningMessageForCHE"/> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput="We can't retrieve a rate from https://free.currconv.com for RHD." stepKey="seeWarningMessageForRHD"/> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput="We can't retrieve a rate from https://free.currconv.com for CHW." stepKey="seeWarningMessageForCHW"/> + <see selector="{{AdminMessagesSection.warning}}" userInput='Click "Save" to apply the rates we found.' stepKey="seeImportMessage"/> + <see selector="{{AdminMessagesSection.warning}}" userInput="We can't retrieve a rate from https://free.currconv.com for CHE." stepKey="seeWarningMessageForCHE"/> + <see selector="{{AdminMessagesSection.warning}}" userInput="We can't retrieve a rate from https://free.currconv.com for RHD." stepKey="seeWarningMessageForRHD"/> + <see selector="{{AdminMessagesSection.warning}}" userInput="We can't retrieve a rate from https://free.currconv.com for CHW." stepKey="seeWarningMessageForCHW"/> <actionGroup ref="AdminSaveCurrencyRatesActionGroup" stepKey="saveCurrencyRates"/> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput='Please correct the input data for "USD => CHE" rate' stepKey="seeCHEMessageAfterSave"/> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput='Please correct the input data for "USD => RHD" rate' stepKey="seeRHDMessageAfterSave"/> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput='Please correct the input data for "USD => CHW" rate' stepKey="seeCHWMessageAfterSave"/> + <see selector="{{AdminMessagesSection.warning}}" userInput='Please correct the input data for "USD => CHE" rate' stepKey="seeCHEMessageAfterSave"/> + <see selector="{{AdminMessagesSection.warning}}" userInput='Please correct the input data for "USD => RHD" rate' stepKey="seeRHDMessageAfterSave"/> + <see selector="{{AdminMessagesSection.warning}}" userInput='Please correct the input data for "USD => CHW" rate' stepKey="seeCHWMessageAfterSave"/> <!--Go to the Storefront and check currency rates--> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryPageLoad"/> @@ -74,6 +74,6 @@ <actionGroup ref="AdminImportCurrencyRatesActionGroup" stepKey="importCurrencyRatesGreaterThen10"> <argument name="rateService" value="Currency Converter API"/> </actionGroup> - <see selector="{{AdminMessagesSection.warningMessage}}" userInput="Too many pairs. Maximum of 10 is supported for the free version." stepKey="seeTooManyPairsMessage"/> + <see selector="{{AdminMessagesSection.warning}}" userInput="Too many pairs. Maximum of 10 is supported for the free version." stepKey="seeTooManyPairsMessage"/> </test> </tests> diff --git a/app/code/Magento/Customer/CustomerData/SectionConfigConverter.php b/app/code/Magento/Customer/CustomerData/SectionConfigConverter.php index c9a93c708e348..51a063b5562bb 100644 --- a/app/code/Magento/Customer/CustomerData/SectionConfigConverter.php +++ b/app/code/Magento/Customer/CustomerData/SectionConfigConverter.php @@ -24,15 +24,7 @@ public function convert($source) foreach ($source->getElementsByTagName('action') as $action) { $actionName = strtolower($action->getAttribute('name')); foreach ($action->getElementsByTagName('section') as $section) { - $sectionName = strtolower($section->getAttribute('name')); - - if ($sectionName === self::INVALIDATE_ALL_SECTIONS_MARKER) { - $sections[$actionName] = []; - $sections[$actionName][] = self::INVALIDATE_ALL_SECTIONS_MARKER; - break; - } else { - $sections[$actionName][] = $sectionName; - } + $sections[$actionName][] = strtolower($section->getAttribute('name')); } if (!isset($sections[$actionName])) { $sections[$actionName][] = self::INVALIDATE_ALL_SECTIONS_MARKER; diff --git a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php index 296d2877df8ea..83aa29ea45265 100644 --- a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php +++ b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php @@ -50,13 +50,6 @@ public function getAllOptions($withEmpty = true, $defaultValues = false) $groups = $this->_groupManagement->getLoggedInGroups(); $this->_options = $this->_converter->toOptionArray($groups, 'id', 'code'); - - array_walk( - $this->_options, - function (&$item) { - $item['__disableTmpl'] = true; - } - ); } return $this->_options; diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php index 0b7c618e6a18b..38e597e4e0fe7 100644 --- a/app/code/Magento/Customer/Model/Customer/DataProvider.php +++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php @@ -365,6 +365,7 @@ private function processWebsiteMeta(&$meta) if (isset($meta[AddressInterface::COUNTRY_ID]) && !$this->getShareConfig()->isGlobalScope()) { $meta[AddressInterface::COUNTRY_ID]['arguments']['data']['config']['filterBy'] = [ 'target' => '${ $.provider }:data.customer.website_id', + '__disableTmpl' => ['target' => false], 'field' => 'website_ids' ]; } @@ -375,7 +376,7 @@ private function processWebsiteMeta(&$meta) * * @param AttributeInterface $attribute * @param array $meta - * @return array + * @return void */ private function processFrontendInput(AttributeInterface $attribute, array &$meta) { diff --git a/app/code/Magento/Customer/Model/EmailNotification.php b/app/code/Magento/Customer/Model/EmailNotification.php index 432317444f4b7..55d82e0d7ccbe 100644 --- a/app/code/Magento/Customer/Model/EmailNotification.php +++ b/app/code/Magento/Customer/Model/EmailNotification.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Customer\Model; @@ -15,6 +16,8 @@ use Magento\Customer\Api\Data\CustomerInterface; use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Framework\Exception\LocalizedException; +use Magento\Store\Model\ScopeInterface; +use Magento\Customer\Model\Data\CustomerSecure; /** * Customer email notification @@ -124,7 +127,7 @@ public function __construct( $this->customerViewHelper = $customerViewHelper; $this->dataProcessor = $dataProcessor; $this->scopeConfig = $scopeConfig; - $this->senderResolver = $senderResolver ?: ObjectManager::getInstance()->get(SenderResolverInterface::class); + $this->senderResolver = $senderResolver ?? ObjectManager::getInstance()->get(SenderResolverInterface::class); } /** @@ -139,7 +142,7 @@ public function credentialsChanged( CustomerInterface $savedCustomer, $origCustomerEmail, $isPasswordChanged = false - ) { + ): void { if ($origCustomerEmail != $savedCustomer->getEmail()) { if ($isPasswordChanged) { $this->emailAndPasswordChanged($savedCustomer, $origCustomerEmail); @@ -164,10 +167,10 @@ public function credentialsChanged( * @param string $email * @return void */ - private function emailAndPasswordChanged(CustomerInterface $customer, $email) + private function emailAndPasswordChanged(CustomerInterface $customer, $email): void { $storeId = $customer->getStoreId(); - if (!$storeId) { + if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } @@ -190,10 +193,10 @@ private function emailAndPasswordChanged(CustomerInterface $customer, $email) * @param string $email * @return void */ - private function emailChanged(CustomerInterface $customer, $email) + private function emailChanged(CustomerInterface $customer, $email): void { $storeId = $customer->getStoreId(); - if (!$storeId) { + if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } @@ -215,10 +218,10 @@ private function emailChanged(CustomerInterface $customer, $email) * @param CustomerInterface $customer * @return void */ - private function passwordReset(CustomerInterface $customer) + private function passwordReset(CustomerInterface $customer): void { $storeId = $customer->getStoreId(); - if (!$storeId) { + if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } @@ -252,15 +255,15 @@ private function sendEmailTemplate( $templateParams = [], $storeId = null, $email = null - ) { - $templateId = $this->scopeConfig->getValue($template, 'store', $storeId); + ): void { + $templateId = $this->scopeConfig->getValue($template, ScopeInterface::SCOPE_STORE, $storeId); if ($email === null) { $email = $customer->getEmail(); } /** @var array $from */ $from = $this->senderResolver->resolve( - $this->scopeConfig->getValue($sender, 'store', $storeId), + $this->scopeConfig->getValue($sender, ScopeInterface::SCOPE_STORE, $storeId), $storeId ); @@ -278,15 +281,15 @@ private function sendEmailTemplate( * Create an object with data merged from Customer and CustomerSecure * * @param CustomerInterface $customer - * @return \Magento\Customer\Model\Data\CustomerSecure + * @return CustomerSecure */ - private function getFullCustomerObject($customer) + private function getFullCustomerObject($customer): CustomerSecure { // No need to flatten the custom attributes or nested objects since the only usage is for email templates and // object passed for events $mergedCustomerData = $this->customerRegistry->retrieveSecureData($customer->getId()); $customerData = $this->dataProcessor - ->buildOutputDataArray($customer, \Magento\Customer\Api\Data\CustomerInterface::class); + ->buildOutputDataArray($customer, CustomerInterface::class); $mergedCustomerData->addData($customerData); $mergedCustomerData->setData('name', $this->customerViewHelper->getCustomerName($customer)); return $mergedCustomerData; @@ -299,7 +302,7 @@ private function getFullCustomerObject($customer) * @param int|string|null $defaultStoreId * @return int */ - private function getWebsiteStoreId($customer, $defaultStoreId = null) + private function getWebsiteStoreId($customer, $defaultStoreId = null): int { if ($customer->getWebsiteId() != 0 && empty($defaultStoreId)) { $storeIds = $this->storeManager->getWebsite($customer->getWebsiteId())->getStoreIds(); @@ -314,10 +317,10 @@ private function getWebsiteStoreId($customer, $defaultStoreId = null) * @param CustomerInterface $customer * @return void */ - public function passwordReminder(CustomerInterface $customer) + public function passwordReminder(CustomerInterface $customer): void { $storeId = $customer->getStoreId(); - if (!$storeId) { + if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } @@ -338,10 +341,10 @@ public function passwordReminder(CustomerInterface $customer) * @param CustomerInterface $customer * @return void */ - public function passwordResetConfirmation(CustomerInterface $customer) + public function passwordResetConfirmation(CustomerInterface $customer): void { $storeId = $customer->getStoreId(); - if (!$storeId) { + if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer); } @@ -362,7 +365,7 @@ public function passwordResetConfirmation(CustomerInterface $customer) * @param CustomerInterface $customer * @param string $type * @param string $backUrl - * @param int $storeId + * @param int|null $storeId * @param string $sendemailStoreId * @return void * @throws LocalizedException @@ -371,9 +374,9 @@ public function newAccount( CustomerInterface $customer, $type = self::NEW_ACCOUNT_EMAIL_REGISTERED, $backUrl = '', - $storeId = 0, + $storeId = null, $sendemailStoreId = null - ) { + ): void { $types = self::TEMPLATE_TYPES; if (!isset($types[$type])) { @@ -382,7 +385,7 @@ public function newAccount( ); } - if (!$storeId) { + if ($storeId === null) { $storeId = $this->getWebsiteStoreId($customer, $sendemailStoreId); } diff --git a/app/code/Magento/Customer/Model/Layout/DepersonalizePlugin.php b/app/code/Magento/Customer/Model/Layout/DepersonalizePlugin.php index 2bb9934933839..66b8f8419deae 100644 --- a/app/code/Magento/Customer/Model/Layout/DepersonalizePlugin.php +++ b/app/code/Magento/Customer/Model/Layout/DepersonalizePlugin.php @@ -1,108 +1,113 @@ <?php /** - * Depersonalize customer session data - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Customer\Model\Layout; +use Magento\Customer\Model\CustomerFactory; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Customer\Model\Visitor; +use Magento\Framework\Data\Form\FormKey; +use Magento\Framework\Session\SessionManagerInterface; +use Magento\Framework\View\LayoutInterface; use Magento\PageCache\Model\DepersonalizeChecker; /** - * Class DepersonalizePlugin + * Depersonalize customer data. + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class DepersonalizePlugin { /** * @var DepersonalizeChecker */ - protected $depersonalizeChecker; + private $depersonalizeChecker; /** - * @var \Magento\Framework\Session\SessionManagerInterface + * @var SessionManagerInterface */ - protected $session; + private $session; /** - * @var \Magento\Customer\Model\Session + * @var CustomerSession */ - protected $customerSession; + private $customerSession; /** - * @var \Magento\Customer\Model\CustomerFactory + * @var CustomerFactory */ - protected $customerFactory; + private $customerFactory; /** - * @var \Magento\Customer\Model\Visitor + * @var Visitor */ - protected $visitor; + private $visitor; /** * @var int */ - protected $customerGroupId; + private $customerGroupId; /** * @var string */ - protected $formKey; + private $formKey; /** * @param DepersonalizeChecker $depersonalizeChecker - * @param \Magento\Framework\Session\SessionManagerInterface $session - * @param \Magento\Customer\Model\Session $customerSession - * @param \Magento\Customer\Model\CustomerFactory $customerFactory - * @param \Magento\Customer\Model\Visitor $visitor + * @param SessionManagerInterface $session + * @param CustomerSession $customerSession + * @param CustomerFactory $customerFactory + * @param Visitor $visitor */ public function __construct( DepersonalizeChecker $depersonalizeChecker, - \Magento\Framework\Session\SessionManagerInterface $session, - \Magento\Customer\Model\Session $customerSession, - \Magento\Customer\Model\CustomerFactory $customerFactory, - \Magento\Customer\Model\Visitor $visitor + SessionManagerInterface $session, + CustomerSession $customerSession, + CustomerFactory $customerFactory, + Visitor $visitor ) { + $this->depersonalizeChecker = $depersonalizeChecker; $this->session = $session; $this->customerSession = $customerSession; $this->customerFactory = $customerFactory; $this->visitor = $visitor; - $this->depersonalizeChecker = $depersonalizeChecker; } /** - * Before generate Xml + * Retrieve sensitive customer data. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @return array + * @param LayoutInterface $subject + * @return void */ - public function beforeGenerateXml(\Magento\Framework\View\LayoutInterface $subject) + public function beforeGenerateXml(LayoutInterface $subject) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->customerGroupId = $this->customerSession->getCustomerGroupId(); - $this->formKey = $this->session->getData(\Magento\Framework\Data\Form\FormKey::FORM_KEY); + $this->formKey = $this->session->getData(FormKey::FORM_KEY); } - return []; } /** - * After generate Xml + * Change sensitive customer data if the depersonalization is needed. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @param \Magento\Framework\View\LayoutInterface $result - * @return \Magento\Framework\View\LayoutInterface + * @param LayoutInterface $subject + * @return void */ - public function afterGenerateXml(\Magento\Framework\View\LayoutInterface $subject, $result) + public function afterGenerateElements(LayoutInterface $subject) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->visitor->setSkipRequestLogging(true); $this->visitor->unsetData(); $this->session->clearStorage(); $this->customerSession->clearStorage(); - $this->session->setData(\Magento\Framework\Data\Form\FormKey::FORM_KEY, $this->formKey); + $this->session->setData(FormKey::FORM_KEY, $this->formKey); $this->customerSession->setCustomerGroupId($this->customerGroupId); $this->customerSession->setCustomer($this->customerFactory->create()->setGroupId($this->customerGroupId)); } - return $result; } } diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AssertStorefrontDefaultWelcomeMessageActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AssertStorefrontDefaultWelcomeMessageActionGroup.xml index eb66cafe43dd3..7cfbc0283d505 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AssertStorefrontDefaultWelcomeMessageActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AssertStorefrontDefaultWelcomeMessageActionGroup.xml @@ -13,8 +13,8 @@ <description>Validates that the Welcome message is present and correct and not you link absent.</description> </annotations> - <waitForElementVisible selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="waitDefaultMessage"/> - <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="verifyDefaultMessage"/> + <waitForElementVisible selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="waitDefaultMessage"/> + <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="verifyDefaultMessage"/> <dontSeeElement selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="checkAbsenceLinkNotYou"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/EnterCustomerAddressInfoFillStateActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/EnterCustomerAddressInfoFillStateActionGroup.xml index 891b578e54e6b..257c9d5039c61 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/EnterCustomerAddressInfoFillStateActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/EnterCustomerAddressInfoFillStateActionGroup.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="EnterCustomerAddressInfoFillStateActionGroup" extends="EnterCustomerAddressInfoActionGroup"> <annotations> - <description>EXTENDS: EnterCustomerAddressInfo. Fills the State field.</description> + <description>EXTENDS: EnterCustomerAddressInfoActionGroup. Fills the State field.</description> </annotations> <fillField stepKey="selectState" selector="{{StorefrontCustomerAddressSection.stateProvinceFill}}" userInput="{{Address.state}}"/> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml index 59601a58e64c7..56afa8854ce0d 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="SignUpNewUserFromStorefrontActionGroup" deprecated="Avoid using super-ActionGroups. See StorefrontCreateCustomerTest for replacement."> + <actionGroup name="SignUpNewUserFromStorefrontActionGroup"> <annotations> <description>Goes to the Storefront. Clicks on 'Create Account'. Fills in the provided Customer details, excluding Newsletter Sign-Up. Clicks on 'Create Account' button. Validate that the Customer details are present and correct.</description> </annotations> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminCreateCustomerWithWebSiteAndGroupActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminCreateCustomerWithWebSiteAndGroupActionGroup.xml deleted file mode 100644 index 37b543f68935a..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminCreateCustomerWithWebSiteAndGroupActionGroup.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminCreateCustomerWithWebSiteAndGroup" deprecated="Use `AdminCreateCustomerWithWebSiteAndGroupActionGroup` instead"> - <annotations> - <description>Goes to the Customer grid page. Click on 'Add New Customer'. Fills provided Customer Data. Fill provided Customer Address data. Assigns Product to Website and Store View. Clicks on Save.</description> - </annotations> - <arguments> - <argument name="customerData" defaultValue="Simple_US_Customer"/> - <argument name="website" type="string" defaultValue="{{_defaultWebsite.name}}"/> - <argument name="storeView" type="string" defaultValue="{{_defaultStore.name}}"/> - </arguments> - - <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersPage"/> - <click stepKey="addNewCustomer" selector="{{AdminCustomerGridMainActionsSection.addNewCustomer}}"/> - <selectOption stepKey="selectWebSite" selector="{{AdminCustomerAccountInformationSection.associateToWebsite}}" userInput="{{website}}"/> - <selectOption selector="{{AdminCustomerAccountInformationSection.group}}" userInput="{{customerData.group}}" stepKey="selectCustomerGroup"/> - <fillField stepKey="FillFirstName" selector="{{AdminCustomerAccountInformationSection.firstName}}" userInput="{{customerData.firstname}}"/> - <fillField stepKey="FillLastName" selector="{{AdminCustomerAccountInformationSection.lastName}}" userInput="{{customerData.lastname}}"/> - <fillField stepKey="FillEmail" selector="{{AdminCustomerAccountInformationSection.email}}" userInput="{{customerData.email}}"/> - <selectOption stepKey="selectStoreView" selector="{{AdminCustomerAccountInformationSection.storeView}}" userInput="{{storeView}}"/> - <waitForElement selector="{{AdminCustomerAccountInformationSection.storeView}}" stepKey="waitForCustomerStoreViewExpand"/> - <click stepKey="save" selector="{{AdminCustomerAccountInformationSection.saveCustomer}}"/> - <waitForPageLoad stepKey="waitForCustomersPage"/> - <see stepKey="seeSuccessMessage" userInput="You saved the customer."/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminEditCustomerAddressNoZipNoStateActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminEditCustomerAddressNoZipNoStateActionGroup.xml deleted file mode 100644 index ebfd011115459..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminEditCustomerAddressNoZipNoStateActionGroup.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminEditCustomerAddressNoZipNoState" extends="AdminEditCustomerAddressesFrom" deprecated="Use `AdminEditCustomerAddressNoZipNoStateActionGroup` instead"> - <annotations> - <description>EXTENDS: AdminEditCustomerAddressesFrom. Removes 'selectState' and 'fillZipCode'. Clicks on 'Set Default' for Billing/Shipping.</description> - </annotations> - - <remove keyForRemoval="selectState"/> - <remove keyForRemoval="fillZipCode"/> - <click selector="{{AdminEditCustomerAddressesSection.defaultBillingAddressButton}}" stepKey="setDefaultBilling" before="setDefaultShipping"/> - <click selector="{{AdminEditCustomerAddressesSection.defaultShippingAddressButton}}" stepKey="setDefaultShipping" before="fillPrefixName"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminEditCustomerAddressSetDefaultShippingAndBillingActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminEditCustomerAddressSetDefaultShippingAndBillingActionGroup.xml deleted file mode 100644 index 326eee275f1f1..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminEditCustomerAddressSetDefaultShippingAndBillingActionGroup.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminEditCustomerAddressSetDefaultShippingAndBilling" extends="AdminEditCustomerAddressesFrom" deprecated="Use `AdminEditCustomerAddressSetDefaultShippingAndBillingActionGroup` instead"> - <annotations> - <description>EXTENDS: AdminEditCustomerAddressesFrom. Removes 'selectState' and 'fillZipCode'.</description> - </annotations> - - <click selector="{{AdminEditCustomerAddressesSection.defaultBillingAddressButton}}" stepKey="setDefaultBilling" before="setDefaultShipping"/> - <click selector="{{AdminEditCustomerAddressesSection.defaultShippingAddressButton}}" stepKey="setDefaultShipping" before="fillPrefixName"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/EnterCustomerAddressInfoActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/EnterCustomerAddressInfoActionGroup.xml deleted file mode 100644 index 0634e0564f04b..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/EnterCustomerAddressInfoActionGroup.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="EnterCustomerAddressInfo" deprecated="Use `EnterCustomerAddressInfoActionGroup` instead"> - <annotations> - <description>Fills in the provided Customer details (First/Last Name, Company, Phone # and Address) on the Admin Customer creation/edit page. Clicks on the Save button.</description> - </annotations> - <arguments> - <argument name="Address"/> - </arguments> - - <amOnPage url="customer/address/new/" stepKey="goToAddressPage"/> - <waitForPageLoad stepKey="waitForAddressPage"/> - <fillField stepKey="fillFirstName" selector="{{StorefrontCustomerAddressSection.firstName}}" userInput="{{Address.firstname}}"/> - <fillField stepKey="fillLastName" selector="{{StorefrontCustomerAddressSection.lastName}}" userInput="{{Address.lastname}}"/> - <fillField stepKey="fillCompany" selector="{{StorefrontCustomerAddressSection.company}}" userInput="{{Address.company}}"/> - <fillField stepKey="fillPhoneNumber" selector="{{StorefrontCustomerAddressSection.phoneNumber}}" userInput="{{Address.telephone}}"/> - <fillField stepKey="fillStreetAddress1" selector="{{StorefrontCustomerAddressSection.streetAddress1}}" userInput="{{Address.street[0]}}"/> - <fillField stepKey="fillStreetAddress2" selector="{{StorefrontCustomerAddressSection.streetAddress2}}" userInput="{{Address.street[1]}}"/> - <fillField stepKey="fillCityName" selector="{{StorefrontCustomerAddressSection.city}}" userInput="{{Address.city}}"/> - <selectOption stepKey="selectCounty" selector="{{StorefrontCustomerAddressSection.country}}" userInput="{{Address.country_id}}"/> - <selectOption stepKey="selectState" selector="{{StorefrontCustomerAddressSection.stateProvince}}" userInput="{{Address.state}}"/> - <fillField stepKey="fillZip" selector="{{StorefrontCustomerAddressSection.zip}}" userInput="{{Address.postcode}}"/> - <click stepKey="saveAddress" selector="{{StorefrontCustomerAddressSection.saveAddress}}"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/EnterCustomerAddressInfoFillStateActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/EnterCustomerAddressInfoFillStateActionGroup.xml deleted file mode 100644 index 0705d1d0c8f2a..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/EnterCustomerAddressInfoFillStateActionGroup.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="EnterCustomerAddressInfoFillState" extends="EnterCustomerAddressInfo" deprecated="Use `CreateSystemBackupActionGroup` instead"> - <annotations> - <description>EXTENDS: EnterCustomerAddressInfo. Fills the State field.</description> - </annotations> - - <fillField stepKey="selectState" selector="{{StorefrontCustomerAddressSection.stateProvinceFill}}" userInput="{{Address.state}}"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/NavigateToCustomerGroupPageActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/NavigateToCustomerGroupPageActionGroup.xml deleted file mode 100644 index 606089acf15d6..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/NavigateToCustomerGroupPageActionGroup.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="NavigateToCustomerGroupPage" extends="AdminNavigateToCustomerGroupPageActionGroup" deprecated="Use AdminNavigateToCustomerGroupPageActionGroup"/> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerBillingAddressActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerBillingAddressActionGroup.xml deleted file mode 100644 index dd5bff2d5488c..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerBillingAddressActionGroup.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="VerifyCustomerBillingAddress" deprecated="Use `VerifyCustomerBillingAddressActionGroup` instead"> - <annotations> - <description>Goes to the Storefront Customer Dashboard Address area. Validates that the provided Customer Billing Address is present and correct on the Storefront Customer Dashboard Address section.</description> - </annotations> - <arguments> - <argument name="address"/> - </arguments> - - <amOnPage url="customer/address/index/" stepKey="goToAddressPage"/> - <waitForPageLoad stepKey="waitForAddressPageLoad"/> - - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.firstname}} {{address.lastname}}" stepKey="seeAssertCustomerDefaultBillingAddressFirstnameAndLastname"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.company}}" stepKey="seeAssertCustomerDefaultBillingAddressCompany"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.street[0]}}" stepKey="seeAssertCustomerDefaultBillingAddressStreet"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.street[1]}}" stepKey="seeAssertCustomerDefaultBillingAddressStreet1"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.city}}, {{address.postcode}}" stepKey="seeAssertCustomerDefaultBillingAddressCityAndPostcode"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.country}}" stepKey="seeAssertCustomerDefaultBillingAddressCountry"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.telephone}}" stepKey="seeAssertCustomerDefaultBillingAddressTelephone"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerBillingAddressWithStateActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerBillingAddressWithStateActionGroup.xml deleted file mode 100644 index 47403b23d7026..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerBillingAddressWithStateActionGroup.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="VerifyCustomerBillingAddressWithState" deprecated="Use `VerifyCustomerBillingAddressWithStateActionGroup` instead"> - <annotations> - <description>Goes to the Storefront Customer Dashboard Address area. Validates that the provided Customer Billing Address, including the State, is present and correct.</description> - </annotations> - <arguments> - <argument name="address"/> - </arguments> - - <amOnPage url="customer/address/index/" stepKey="goToAddressPage"/> - <waitForPageLoad stepKey="waitForAddressPageLoad"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.firstname}} {{address.lastname}}" stepKey="seeAssertCustomerDefaultBillingAddressFirstnameAndLastname"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.company}}" stepKey="seeAssertCustomerDefaultBillingAddressCompany"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.street[0]}}" stepKey="seeAssertCustomerDefaultBillingAddressStreet"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.street[1]}}" stepKey="seeAssertCustomerDefaultBillingAddressStreet1"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.city}}, {{address.state}}, {{address.postcode}}" stepKey="seeAssertCustomerDefaultBillingAddressCityAndPostcode"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.country}}" stepKey="seeAssertCustomerDefaultBillingAddressCountry"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultBillingAddress}}" userInput="{{address.telephone}}" stepKey="seeAssertCustomerDefaultBillingAddressTelephone"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerNameOnFrontendActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerNameOnFrontendActionGroup.xml deleted file mode 100644 index cc01f3ade85ac..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerNameOnFrontendActionGroup.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="VerifyCustomerNameOnFrontend" deprecated="Use `VerifyCustomerNameOnFrontendActionGroup` instead"> - <annotations> - <description>Goes to the Storefront Customer Dashboard page. Validates that the Customer First/Last Name is present and correct.</description> - </annotations> - <arguments> - <argument name="customer"/> - </arguments> - - <amOnPage url="customer/account/edit/" stepKey="goToAddressPage"/> - <waitForPageLoad stepKey="waitForAddressPageLoad"/> - <click selector="{{StorefrontCustomerSidebarSection.sidebarCurrentTab('Account Information')}}" stepKey="clickAccountInformationFromSidebarCurrentTab"/> - <waitForPageLoad stepKey="waitForAccountInformationTabToOpen"/> - <seeInField selector="{{StorefrontCustomerAccountInformationSection.firstName}}" userInput="{{customer.firstname}}" stepKey="seeAssertCustomerFirstName"/> - <seeInField selector="{{StorefrontCustomerAccountInformationSection.lastName}}" userInput="{{customer.lastname}}" stepKey="seeAssertCustomerLastName"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerShippingAddressActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerShippingAddressActionGroup.xml deleted file mode 100644 index 1d9f3fd600155..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerShippingAddressActionGroup.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="VerifyCustomerShippingAddress" deprecated="Use `VerifyCustomerShippingAddressActionGroup` instead"> - <annotations> - <description>Goes to the Storefront Customer Dashboard Address area. Validates that the provided Customer Shipping Address is present and correct.</description> - </annotations> - <arguments> - <argument name="address"/> - </arguments> - - <amOnPage url="customer/address/index/" stepKey="goToAddressPage"/> - <waitForPageLoad stepKey="waitForAddressPageLoad"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.firstname}} {{address.lastname}}" stepKey="seeAssertCustomerDefaultShippingAddressFirstnameAndLastname"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.company}}" stepKey="seeAssertCustomerDefaultShippingAddressCompany"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.street[0]}}" stepKey="seeAssertCustomerDefaultShippingAddressStreet"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.street[1]}}" stepKey="seeAssertCustomerDefaultShippingAddressStreet1"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.city}}, {{address.postcode}}" stepKey="seeAssertCustomerDefaultShippingAddressCityAndPostcode"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.country}}" stepKey="seeAssertCustomerDefaultShippingAddressCountry"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.telephone}}" stepKey="seeAssertCustomerDefaultShippingAddressTelephone"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerShippingAddressWithStateActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerShippingAddressWithStateActionGroup.xml deleted file mode 100644 index 3291f9c8a7ef2..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyCustomerShippingAddressWithStateActionGroup.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="VerifyCustomerShippingAddressWithState" deprecated="Use `VerifyCustomerShippingAddressWithStateActionGroup` instead"> - <annotations> - <description>Goes to the Storefront Customer Dashboard Address area. Validates that the provided Customer Shipping Address, including the State, is present and correct.</description> - </annotations> - <arguments> - <argument name="address"/> - </arguments> - - <amOnPage url="customer/address/index/" stepKey="goToAddressPage"/> - <waitForPageLoad stepKey="waitForAddressPageLoad"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.firstname}} {{address.lastname}}" stepKey="seeAssertCustomerDefaultShippingAddressFirstnameAndLastname"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.company}}" stepKey="seeAssertCustomerDefaultShippingAddressCompany"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.street[0]}}" stepKey="seeAssertCustomerDefaultShippingAddressStreet"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.street[1]}}" stepKey="seeAssertCustomerDefaultShippingAddressStreet1"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.city}}, {{address.state}}, {{address.postcode}}" stepKey="seeAssertCustomerDefaultShippingAddressCityAndPostcode"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.country}}" stepKey="seeAssertCustomerDefaultShippingAddressCountry"/> - <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{address.telephone}}" stepKey="seeAssertCustomerDefaultShippingAddressTelephone"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml index e9a21ab9fcfa7..e176c45a1fa00 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml @@ -9,7 +9,7 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> <entity name="CustomerEntityOne" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">defaultBillingValue</data> <data key="default_shipping">defaultShippingValue</data> <data key="confirmation">confirmationData</data> @@ -111,7 +111,7 @@ <data key="website_id">0</data> </entity> <entity name="Simple_US_Customer_Multiple_Addresses" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> @@ -125,7 +125,7 @@ <requiredEntity type="address">UK_Not_Default_Address</requiredEntity> </entity> <entity name="Simple_US_Customer_Multiple_Addresses_No_Default_Address" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> @@ -139,7 +139,7 @@ <requiredEntity type="address">UK_Not_Default_Address</requiredEntity> </entity> <entity name="Simple_US_Customer_With_Different_Billing_Shipping_Addresses" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> @@ -153,7 +153,7 @@ <requiredEntity type="address">US_Address_NY_Default_Shipping</requiredEntity> </entity> <entity name="Simple_US_Customer_NY" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> @@ -166,7 +166,7 @@ <requiredEntity type="address">US_Address_NY</requiredEntity> </entity> <entity name="Simple_US_Customer_CA" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> @@ -221,7 +221,7 @@ <requiredEntity type="address">US_Address_Utah</requiredEntity> </entity> <entity name="Simple_GB_Customer" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">Jane.Doe@example.com</data> @@ -257,7 +257,7 @@ <data key="website_id">0</data> </entity> <entity name="UKCustomer" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">david@email.com</data> @@ -271,7 +271,7 @@ <requiredEntity type="address">updateCustomerUKAddress</requiredEntity> </entity> <entity name="Customer_US_UK_DE" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> @@ -299,7 +299,7 @@ <requiredEntity type="address">US_Address_CA</requiredEntity> </entity> <entity name="Simple_US_Customer_Two_Addresses" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> @@ -331,7 +331,7 @@ <data key="password">123123qa</data> </entity> <entity name="Simple_US_Customer_Incorrect_Email" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email">><script>alert(1);</script>@example.com</data> @@ -354,7 +354,7 @@ <data key="website_id">0</data> </entity> <entity name="Simple_US_Customer_ArmedForcesEurope" type="customer"> - <data key="group_id">0</data> + <data key="group_id">1</data> <data key="default_billing">true</data> <data key="default_shipping">true</data> <data key="email" unique="prefix">John.Doe@example.com</data> diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml index 3610532c5356b..39dd719ce10f4 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml @@ -9,9 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontPanelHeaderSection"> - <!-- Element name="WelcomeMessage" Deprecated due to incorrect naming convention please use name="welcomeMessage" --> - <element name="WelcomeMessage" type="text" selector=".greet.welcome span"/> - <element name="welcomeMessage" type="text" selector="header>.panel .greet.welcome" /> <element name="createAnAccountLink" type="select" selector="//div[@class='panel wrapper']//li/a[contains(.,'Create an Account')]" timeout="30"/> <element name="notYouLink" type="button" selector=".greet.welcome span a"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontTest.xml index 8fe6e220c4aed..444e9aa643181 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateNewCustomerOnStorefrontTest.xml @@ -30,9 +30,15 @@ </after> <!--Create new customer on storefront and perform the asserts--> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="signUpNewUser"> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> <argument name="customer" value="CustomerEntityOne"/> </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> + </actionGroup> <actionGroup ref="AssertSignedUpNewsletterActionGroup" stepKey="assertSignedUpNewsLetter"> <argument name="customer" value="CustomerEntityOne"/> </actionGroup> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/ChangeCustomerGroupTest/ChangingAllCustomerGroupViaGridTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/ChangeCustomerGroupTest/ChangingAllCustomerGroupViaGridTest.xml deleted file mode 100644 index e6c114334000e..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/Test/ChangeCustomerGroupTest/ChangingAllCustomerGroupViaGridTest.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ChangingAllCustomerGroupViaGridTest" extends="ChangingSingleCustomerGroupViaGridTest"> - <annotations> - <title value="DEPRECATED Change all customers' group via grid"/> - <description value="Select All customers to change their group"/> - <severity value="MAJOR"/> - <testCaseId value="MC-10924"/> - <stories value="Change Customer Group"/> - <group value="customer"/> - <group value="mtf_migrated"/> - <skip> - <issueId value="DEPRECATED">Use AdminChangeAllCustomersGroupViaGridTest instead</issueId> - </skip> - </annotations> - - <remove keyForRemoval="filterCustomer"/> - <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearFilters" before="selectCustomer"/> - <actionGroup ref="AdminSelectAllCustomers" stepKey="selectCustomer"/> - </test> -</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/ChangeCustomerGroupTest/ChangingSingleCustomerGroupViaGridTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/ChangeCustomerGroupTest/ChangingSingleCustomerGroupViaGridTest.xml deleted file mode 100644 index 0edadb86888f5..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/Test/ChangeCustomerGroupTest/ChangingSingleCustomerGroupViaGridTest.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="ChangingSingleCustomerGroupViaGridTest"> - <annotations> - <title value="DEPRECATED Change a single customer group via grid"/> - <description value="From the selection of All Customers select a single customer to change their group"/> - <severity value="MAJOR"/> - <testCaseId value="MC-10921"/> - <stories value="Change Customer Group"/> - <group value="customer"/> - <group value="mtf_migrated"/> - <skip> - <issueId value="DEPRECATED">Use AdminChangeSingleCustomerGroupViaGridTest instead</issueId> - </skip> - </annotations> - - <before> - <createData entity="Simple_US_Customer" stepKey="createCustomer"/> - - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - </before> - <after> - <!--Delete created product--> - <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> - <actionGroup ref="NavigateToCustomerGroupPage" stepKey="navToCustomers"/> - <actionGroup ref="AdminDeleteCustomerGroupActionGroup" stepKey="deleteCustomerGroup"> - <argument name="customerGroupName" value="{{CustomerGroupChange.code}}"/> - </actionGroup> - - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - </after> - - <actionGroup ref="AdminCreateCustomerGroupActionGroup" stepKey="createCustomerGroup"> - <argument name="groupName" value="{{CustomerGroupChange.code}}"/> - <argument name="taxClass" value="{{CustomerGroupChange.tax_class_name}}"/> - </actionGroup> - <actionGroup ref="NavigateToAllCustomerPage" stepKey="navToCustomers"/> - <actionGroup ref="AdminFilterCustomerByName" stepKey="filterCustomer"> - <argument name="customerName" value="{{Simple_US_Customer.fullname}}"/> - </actionGroup> - <actionGroup ref="AdminSelectCustomerByEmail" stepKey="selectCustomer"> - <argument name="customerEmail" value="$$createCustomer.email$$"/> - </actionGroup> - <actionGroup ref="SetCustomerGroupForSelectedCustomersViaGrid" stepKey="setCustomerGroup"> - <argument name="groupName" value="{{CustomerGroupChange.code}}"/> - </actionGroup> - <actionGroup ref="AdminFilterCustomerByName" stepKey="filterCustomerAfterGroupChange"> - <argument name="customerName" value="{{Simple_US_Customer.fullname}}"/> - </actionGroup> - <actionGroup ref="VerifyCustomerGroupForCustomer" stepKey="verifyCustomerGroupSet"> - <argument name="customerEmail" value="$$createCustomer.email$$"/> - <argument name="groupName" value="{{CustomerGroupChange.code}}"/> - </actionGroup> - </test> -</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml index 86218647778e6..2b6b1e7d1213c 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml @@ -31,8 +31,14 @@ </after> <!-- Step 0: User signs up an account --> <comment userInput="Start of signing up user account" stepKey="startOfSigningUpUserAccount" /> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <comment userInput="End of signing up user account" stepKey="endOfSigningUpUserAccount" /> </test> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml index 9b4e7716f4a25..80cdeadb391da 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml @@ -67,9 +67,11 @@ </actionGroup> <!--Register customer on storefront--> - <actionGroup ref="SignUpNewCustomerStorefrontActionGroup" stepKey="createAnAccount"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> <!--Go to My account > Address book--> <actionGroup ref="EnterCustomerAddressInfoFillStateActionGroup" stepKey="enterAddressInfo"> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml index f45935b698fb5..b800b7870b5c5 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml @@ -19,9 +19,15 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> </before> <after> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml index 87390beaa50f9..41e0a5d1b7793 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml @@ -19,9 +19,15 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> </before> <after> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressFranceTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressFranceTest.xml index 6a4ed633fd413..1ecfb20b38e19 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressFranceTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressFranceTest.xml @@ -20,9 +20,15 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> </before> <after> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressUKTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressUKTest.xml index b3ad6cc96aae1..8e29452b5495e 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressUKTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressUKTest.xml @@ -20,9 +20,15 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="CustomerEntityOne"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="CustomerEntityOne"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> </before> <after> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontVerifyNoXssInjectionOnUpdateCustomerInformationAddAddressTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontVerifyNoXssInjectionOnUpdateCustomerInformationAddAddressTest.xml index 67aa050907f30..11aed4a3461e1 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontVerifyNoXssInjectionOnUpdateCustomerInformationAddAddressTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontVerifyNoXssInjectionOnUpdateCustomerInformationAddAddressTest.xml @@ -20,9 +20,15 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="Colorado_US_Customer"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Colorado_US_Customer"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> </before> <after> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/AddingProductWithExpiredSessionTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/AddingProductWithExpiredSessionTest.xml deleted file mode 100644 index 2d580ab55075c..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/AddingProductWithExpiredSessionTest.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AddingProductWithExpiredSessionTest" extends="StorefrontAddProductToCartWithExpiredSessionTest" deprecated="Use StorefrontAddProductToCartWithExpiredSessionTest"/> -</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/StorefrontCustomerForgotPasswordTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/StorefrontCustomerForgotPasswordTest.xml deleted file mode 100644 index 7c29e00b6a3a9..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/StorefrontCustomerForgotPasswordTest.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="StorefrontCustomerForgotPasswordTest" extends="StorefrontResetCustomerPasswordSuccessTest" deprecated="Use StorefrontResetCustomerPasswordSuccessTest"/> -</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/VerifyDisabledCustomerGroupFieldTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/VerifyDisabledCustomerGroupFieldTest.xml deleted file mode 100644 index 58e815b03126d..0000000000000 --- a/app/code/Magento/Customer/Test/Mftf/Test/_Deprecated_Test/VerifyDisabledCustomerGroupFieldTest.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="VerifyDisabledCustomerGroupFieldTest" extends="AdminVerifyDisabledCustomerGroupFieldTest" deprecated="Use AdminVerifyDisabledCustomerGroupFieldTest instead"/> -</tests> diff --git a/app/code/Magento/Customer/Test/Unit/CustomerData/SectionConfigConverterTest.php b/app/code/Magento/Customer/Test/Unit/CustomerData/SectionConfigConverterTest.php index b78aa8609607e..44401ca5eb7bf 100644 --- a/app/code/Magento/Customer/Test/Unit/CustomerData/SectionConfigConverterTest.php +++ b/app/code/Magento/Customer/Test/Unit/CustomerData/SectionConfigConverterTest.php @@ -75,12 +75,12 @@ public function testConvert() 'sections' => [ 'sales/guest/reorder' => ['account'], 'sales/order/reorder' => ['account', 'cart'], - 'stores/store/switch' => ['*'], + 'stores/store/switch' => ['account', '*', 'cart'], 'directory/currency/switch' => ['*'], 'customer/account/logout' => ['account', 'cart'], 'customer/account/editpost' => ['account', 'acc', 'cart'], - 'checkout/cart/delete' => ['*'], - 'customer/account/createpost' => ['*'], + 'checkout/cart/delete' => ['account', 'acc', 'cart', '*'], + 'customer/account/createpost' => ['account','*'], 'catalog/product_compare/add' => ['*'], 'catalog/product_compare/remove' => ['account', 'acc'], 'catalog/product_compare/clear' => ['*'], diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php index 8ad7363a1c310..f98759d3f067a 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php @@ -26,7 +26,7 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Ui\Component\Form\Field; use Magento\Ui\DataProvider\EavValidationRules; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use PHPUnit\Framework\MockObject\MockObject; /** * Unit tests for \Magento\Customer\Model\Customer\DataProvider class. @@ -243,6 +243,7 @@ public function getAttributesMetaDataProvider() 'componentType' => Field::NAME, 'filterBy' => [ 'target' => '${ $.provider }:data.customer.website_id', + '__disableTmpl' => ['target' => false], 'field' => 'website_ids', ], ], @@ -1280,6 +1281,7 @@ private function getExpectationForVisibleAttributes() 'componentType' => Field::NAME, 'filterBy' => [ 'target' => '${ $.provider }:data.customer.website_id', + '__disableTmpl' => ['target' => false], 'field' => 'website_ids', ], ], diff --git a/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php b/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php index ff83ef62c6aa7..ab90eacbb6032 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php @@ -3,88 +3,132 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Customer\Test\Unit\Model; use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Helper\View; +use Magento\Customer\Model\CustomerRegistry; +use Magento\Customer\Model\Data\CustomerSecure; use Magento\Customer\Model\EmailNotification; use Magento\Framework\App\Area; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Helper\Context; use Magento\Framework\Mail\Template\SenderResolverInterface; +use Magento\Framework\Mail\Template\TransportBuilder; +use Magento\Framework\Mail\TransportInterface; +use Magento\Framework\Reflection\DataObjectProcessor; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Model\Website; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** - * Class EmailNotificationTest + * Unit test for \Magento\Customer\Model\EmailNotification * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class EmailNotificationTest extends \PHPUnit\Framework\TestCase +class EmailNotificationTest extends TestCase { /** - * @var \Magento\Customer\Model\CustomerRegistry|\PHPUnit_Framework_MockObject_MockObject + * @var int + */ + private const STUB_CUSTOMER_ID = 1; + + /** + * @var int + */ + private const STUB_CUSTOMER_WEBSITE_ID = 1; + + /** + * @var string + */ + private const STUB_CUSTOMER_EMAIL = 'email@email.com'; + + /** + * @var string + */ + private const STUB_CUSTOMER_NAME = 'Customer Name'; + + /** + * @var string + */ + private const STUB_EMAIL_IDENTIFIER = 'Template Identifier'; + + /** + * @var string + */ + private const STUB_SENDER = 'Sender'; + + /** + * @var CustomerRegistry|MockObject */ private $customerRegistryMock; /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var StoreManagerInterface|MockObject */ private $storeManagerMock; /** - * @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var TransportBuilder|MockObject */ private $transportBuilderMock; /** - * @var \Magento\Customer\Helper\View|\PHPUnit_Framework_MockObject_MockObject + * @var View|MockObject */ private $customerViewHelperMock; /** - * @var \Magento\Framework\Reflection\DataObjectProcessor|\PHPUnit_Framework_MockObject_MockObject + * @var DataObjectProcessor|MockObject */ private $dataProcessorMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Model\Data\CustomerSecure + * @var CustomerSecure|MockObject */ private $customerSecureMock; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ private $scopeConfigMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Store\Model\Store + * @var Store|MockObject */ private $storeMock; /** - * @var \Magento\Customer\Model\EmailNotification + * @var EmailNotification */ private $model; /** - * @var SenderResolverInterface|\PHPUnit_Framework_MockObject_MockObject + * @var SenderResolverInterface|MockObject */ private $senderResolverMock; - public function setUp() + /** + * @inheritdoc + */ + public function setUp():void { - $this->customerRegistryMock = $this->createMock(\Magento\Customer\Model\CustomerRegistry::class); - - $this->storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class); - - $this->transportBuilderMock = $this->createMock(\Magento\Framework\Mail\Template\TransportBuilder::class); + $this->customerRegistryMock = $this->createMock(CustomerRegistry::class); + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); + $this->transportBuilderMock = $this->createMock(TransportBuilder::class); + $this->customerViewHelperMock = $this->createMock(View::class); + $this->dataProcessorMock = $this->createMock(DataObjectProcessor::class); - $this->customerViewHelperMock = $this->createMock(\Magento\Customer\Helper\View::class); - - $this->dataProcessorMock = $this->createMock(\Magento\Framework\Reflection\DataObjectProcessor::class); - - $contextMock = $this->createPartialMock(\Magento\Framework\App\Helper\Context::class, ['getScopeConfig']); + $contextMock = $this->createPartialMock(Context::class, ['getScopeConfig']); $this->scopeConfigMock = $this->createPartialMock( - \Magento\Framework\App\Config\ScopeConfigInterface::class, + ScopeConfigInterface::class, ['getValue', 'isSetFlag'] ); @@ -92,16 +136,16 @@ public function setUp() ->method('getScopeConfig') ->willReturn($this->scopeConfigMock); - $this->customerSecureMock = $this->createMock(\Magento\Customer\Model\Data\CustomerSecure::class); + $this->customerSecureMock = $this->createMock(CustomerSecure::class); - $this->storeMock = $this->createMock(\Magento\Store\Model\Store::class); + $this->storeMock = $this->createMock(Store::class); $this->senderResolverMock = $this->getMockBuilder(SenderResolverInterface::class) ->setMethods(['resolve']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $objectManager = new ObjectManagerHelper($this); $this->model = $objectManager->getObject( EmailNotification::class, @@ -118,24 +162,27 @@ public function setUp() } /** + * Test email notify when credentials changed + * * @param int $testNumber + * @param int $customerStoreId * @param string $oldEmail * @param string $newEmail * @param bool $isPasswordChanged - * * @dataProvider sendNotificationEmailsDataProvider + * + * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPasswordChanged) - { - $customerId = 1; - $customerStoreId = 2; - $customerWebsiteId = 1; + public function testEmailNotifyWhenCredentialsChanged( + $testNumber, + $customerStoreId, + $oldEmail, + $newEmail, + $isPasswordChanged + ):void { $customerData = ['key' => 'value']; - $customerName = 'Customer Name'; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - $senderValues = ['name' => $sender, 'email' => $sender]; + $senderValues = ['name' => self::STUB_SENDER, 'email' => self::STUB_SENDER]; $expects = $this->once(); $xmlPathTemplate = EmailNotification::XML_PATH_RESET_PASSWORD_TEMPLATE; @@ -145,7 +192,7 @@ public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPas $expects = $this->once(); break; case 2: - $xmlPathTemplate = \Magento\Customer\Model\EmailNotification::XML_PATH_CHANGE_EMAIL_TEMPLATE; + $xmlPathTemplate = EmailNotification::XML_PATH_CHANGE_EMAIL_TEMPLATE; $expects = $this->exactly(2); break; case 3: @@ -157,22 +204,23 @@ public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPas $this->senderResolverMock ->expects($expects) ->method('resolve') - ->with($sender, $customerStoreId) + ->with(self::STUB_SENDER, $customerStoreId) ->willReturn($senderValues); - /** @var \PHPUnit_Framework_MockObject_MockObject $origCustomer */ - $origCustomer = $this->createMock(CustomerInterface::class); - $origCustomer->expects($this->any()) + /** + * @var MockObject $origCustomerMock + */ + $origCustomerMock = $this->createMock(CustomerInterface::class); + $origCustomerMock->expects($this->any()) ->method('getStoreId') - ->willReturn(0); - $origCustomer->expects($this->any()) + ->willReturn($customerStoreId); + $origCustomerMock->expects($this->any()) ->method('getId') - ->willReturn($customerId); - $origCustomer->expects($this->any()) - ->method('getWebsiteId') - ->willReturn($customerWebsiteId); + ->willReturn(self::STUB_CUSTOMER_ID); + $origCustomerMock->expects($this->never()) + ->method('getWebsiteId'); - $storeMock = $this->createMock(\Magento\Store\Model\Store::class); + $storeMock = $this->createMock(Store::class); $storeMock->expects($this->any()) ->method('getId') ->willReturn($customerStoreId); @@ -181,31 +229,29 @@ public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPas ->method('getStore') ->willReturn($storeMock); - $websiteMock = $this->createPartialMock(\Magento\Store\Model\Website::class, ['getStoreIds']); + $websiteMock = $this->createPartialMock(Website::class, ['getStoreIds']); $websiteMock->expects($this->any()) ->method('getStoreIds') ->willReturn([$customerStoreId]); - $this->storeManagerMock->expects(clone $expects) - ->method('getWebsite') - ->with($customerWebsiteId) - ->willReturn($websiteMock); + $this->storeManagerMock->expects($this->never()) + ->method('getWebsite'); - $customerSecureMock = $this->createMock(\Magento\Customer\Model\Data\CustomerSecure::class); + $customerSecureMock = $this->createMock(CustomerSecure::class); $this->customerRegistryMock->expects(clone $expects) ->method('retrieveSecureData') - ->with($customerId) + ->with(self::STUB_CUSTOMER_ID) ->willReturn($customerSecureMock); $this->dataProcessorMock->expects(clone $expects) ->method('buildOutputDataArray') - ->with($origCustomer, CustomerInterface::class) + ->with($origCustomerMock, CustomerInterface::class) ->willReturn($customerData); $this->customerViewHelperMock->expects($this->any()) ->method('getCustomerName') - ->with($origCustomer) - ->willReturn($customerName); + ->with($origCustomerMock) + ->willReturn(self::STUB_CUSTOMER_NAME); $customerSecureMock->expects(clone $expects) ->method('addData') @@ -213,13 +259,15 @@ public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPas ->willReturnSelf(); $customerSecureMock->expects(clone $expects) ->method('setData') - ->with('name', $customerName) + ->with('name', self::STUB_CUSTOMER_NAME) ->willReturnSelf(); - /** @var CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $savedCustomer */ - $savedCustomer = clone $origCustomer; + /** + * @var CustomerInterface|MockObject $savedCustomer + */ + $savedCustomer = clone $origCustomerMock; - $origCustomer->expects($this->any()) + $origCustomerMock->expects($this->any()) ->method('getEmail') ->willReturn($oldEmail); @@ -230,28 +278,40 @@ public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPas $this->scopeConfigMock->expects($this->any()) ->method('getValue') ->withConsecutive( - [$xmlPathTemplate, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $customerStoreId], [ - \Magento\Customer\Model\EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $xmlPathTemplate, + ScopeInterface::SCOPE_STORE, + $customerStoreId + ], + [ + EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, + ScopeInterface::SCOPE_STORE, + $customerStoreId + ], + [ + $xmlPathTemplate, + ScopeInterface::SCOPE_STORE, $customerStoreId ], - [$xmlPathTemplate, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $customerStoreId], [ - \Magento\Customer\Model\EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, + ScopeInterface::SCOPE_STORE, $customerStoreId ] - ) - ->willReturnOnConsecutiveCalls($templateIdentifier, $sender, $templateIdentifier, $sender); + )->willReturnOnConsecutiveCalls( + self::STUB_EMAIL_IDENTIFIER, + self::STUB_SENDER, + self::STUB_EMAIL_IDENTIFIER, + self::STUB_SENDER + ); $this->transportBuilderMock->expects(clone $expects) ->method('setTemplateIdentifier') - ->with($templateIdentifier) + ->with(self::STUB_EMAIL_IDENTIFIER) ->willReturnSelf(); $this->transportBuilderMock->expects(clone $expects) ->method('setTemplateOptions') - ->with(['area' => \Magento\Framework\App\Area::AREA_FRONTEND, 'store' => $customerStoreId]) + ->with(['area' => Area::AREA_FRONTEND, 'store' => $customerStoreId]) ->willReturnSelf(); $this->transportBuilderMock->expects(clone $expects) ->method('setTemplateVars') @@ -264,10 +324,10 @@ public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPas $this->transportBuilderMock->expects(clone $expects) ->method('addTo') - ->withConsecutive([$oldEmail, $customerName], [$newEmail, $customerName]) + ->withConsecutive([$oldEmail, self::STUB_CUSTOMER_NAME], [$newEmail, self::STUB_CUSTOMER_NAME]) ->willReturnSelf(); - $transport = $this->createMock(\Magento\Framework\Mail\TransportInterface::class); + $transport = $this->createMock(TransportInterface::class); $this->transportBuilderMock->expects(clone $expects) ->method('getTransport') @@ -280,25 +340,52 @@ public function testCredentialsChanged($testNumber, $oldEmail, $newEmail, $isPas } /** + * Provides Emails Data Provider + * + * @param void * @return array */ - public function sendNotificationEmailsDataProvider() + public function sendNotificationEmailsDataProvider(): array { return [ [ 'test_number' => 1, + 'customerStoreId' => 0, 'old_email' => 'test@example.com', 'new_email' => 'test@example.com', 'is_password_changed' => true ], + [ + 'test_number' => 1, + 'customerStoreId' => 2, + 'old_email' => 'test@example.com', + 'new_email' => 'test@example.com', + 'is_password_changed' => true + ], + [ + 'test_number' => 2, + 'customerStoreId' => 0, + 'old_email' => 'test1@example.com', + 'new_email' => 'test2@example.com', + 'is_password_changed' => false + ], [ 'test_number' => 2, + 'customerStoreId' => 2, 'old_email' => 'test1@example.com', 'new_email' => 'test2@example.com', 'is_password_changed' => false ], [ 'test_number' => 3, + 'customerStoreId' => 0, + 'old_email' => 'test1@example.com', + 'new_email' => 'test2@example.com', + 'is_password_changed' => true + ], + [ + 'test_number' => 3, + 'customerStoreId' => 2, 'old_email' => 'test1@example.com', 'new_email' => 'test2@example.com', 'is_password_changed' => true @@ -307,41 +394,43 @@ public function sendNotificationEmailsDataProvider() } /** + * Test Password Reminder Email Notify + * + * @param int $customerStoreId + * @dataProvider customerStoreIdDataProvider + * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testPasswordReminder() + public function testPasswordReminder($customerStoreId):void { - $customerId = 1; - $customerWebsiteId = 1; - $customerStoreId = 2; - $customerEmail = 'email@email.com'; $customerData = ['key' => 'value']; - $customerName = 'Customer Name'; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - $senderValues = ['name' => $sender, 'email' => $sender]; + $senderValues = ['name' => self::STUB_SENDER, 'email' => self::STUB_SENDER]; $storeIds = [1, 2]; $this->senderResolverMock ->expects($this->once()) ->method('resolve') - ->with($sender, $customerStoreId) + ->with(self::STUB_SENDER, $customerStoreId) ->willReturn($senderValues); - /** @var CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ - $customer = $this->createMock(CustomerInterface::class); - $customer->expects($this->any()) + /** + * @var CustomerInterface|MockObject $customerMock + */ + $customerMock = $this->createMock(CustomerInterface::class); + $customerMock->expects($this->never()) + ->method('getWebsiteId'); + $customerMock->expects($this->any()) ->method('getWebsiteId') - ->willReturn($customerWebsiteId); - $customer->expects($this->any()) + ->willReturn(self::STUB_CUSTOMER_WEBSITE_ID); + $customerMock->expects($this->any()) ->method('getStoreId') ->willReturn($customerStoreId); - $customer->expects($this->any()) + $customerMock->expects($this->any()) ->method('getId') - ->willReturn($customerId); - $customer->expects($this->any()) + ->willReturn(self::STUB_CUSTOMER_ID); + $customerMock->expects($this->any()) ->method('getEmail') - ->willReturn($customerEmail); + ->willReturn(self::STUB_CUSTOMER_EMAIL); $this->storeMock->expects($this->any()) ->method('getId') @@ -351,30 +440,30 @@ public function testPasswordReminder() ->method('getStore') ->willReturn($this->storeMock); - $websiteMock = $this->createPartialMock(\Magento\Store\Model\Website::class, ['getStoreIds']); + $websiteMock = $this->createPartialMock(Website::class, ['getStoreIds']); $websiteMock->expects($this->any()) ->method('getStoreIds') ->willReturn($storeIds); $this->storeManagerMock->expects($this->any()) ->method('getWebsite') - ->with($customerWebsiteId) + ->with(self::STUB_CUSTOMER_WEBSITE_ID) ->willReturn($websiteMock); $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') - ->with($customerId) + ->with(self::STUB_CUSTOMER_ID) ->willReturn($this->customerSecureMock); $this->dataProcessorMock->expects($this->once()) ->method('buildOutputDataArray') - ->with($customer, CustomerInterface::class) + ->with($customerMock, CustomerInterface::class) ->willReturn($customerData); $this->customerViewHelperMock->expects($this->any()) ->method('getCustomerName') - ->with($customer) - ->willReturn($customerName); + ->with($customerMock) + ->willReturn(self::STUB_CUSTOMER_NAME); $this->customerSecureMock->expects($this->once()) ->method('addData') @@ -382,65 +471,69 @@ public function testPasswordReminder() ->willReturnSelf(); $this->customerSecureMock->expects($this->once()) ->method('setData') - ->with('name', $customerName) + ->with('name', self::STUB_CUSTOMER_NAME) ->willReturnSelf(); $this->scopeConfigMock->expects($this->at(0)) ->method('getValue') - ->with(EmailNotification::XML_PATH_REMIND_EMAIL_TEMPLATE, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($templateIdentifier); + ->with( + EmailNotification::XML_PATH_REMIND_EMAIL_TEMPLATE, + ScopeInterface::SCOPE_STORE, + $customerStoreId + )->willReturn(self::STUB_EMAIL_IDENTIFIER); $this->scopeConfigMock->expects($this->at(1)) ->method('getValue') - ->with(EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($sender); + ->with( + EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, + ScopeInterface::SCOPE_STORE, + $customerStoreId + )->willReturn(self::STUB_SENDER); $this->mockDefaultTransportBuilder( - $templateIdentifier, + self::STUB_EMAIL_IDENTIFIER, $customerStoreId, $senderValues, - $customerEmail, - $customerName, + self::STUB_CUSTOMER_EMAIL, + self::STUB_CUSTOMER_NAME, ['customer' => $this->customerSecureMock, 'store' => $this->storeMock] ); - $this->model->passwordReminder($customer); + $this->model->passwordReminder($customerMock); } /** + * Test password reminder customer withouer store id info + * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testPasswordReminderCustomerWithoutStoreId() + public function testPasswordReminderCustomerWithoutStoreId():void { - $customerId = 1; - $customerWebsiteId = 1; $customerStoreId = null; - $customerEmail = 'email@email.com'; $customerData = ['key' => 'value']; - $customerName = 'Customer Name'; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - $senderValues = ['name' => $sender, 'email' => $sender]; + $senderValues = ['name' => self::STUB_SENDER, 'email' => self::STUB_SENDER]; $storeIds = [1, 2]; $defaultStoreId = reset($storeIds); $this->senderResolverMock ->expects($this->once()) ->method('resolve') - ->with($sender, $defaultStoreId) + ->with(self::STUB_SENDER, $defaultStoreId) ->willReturn($senderValues); - /** @var CustomerInterface | \PHPUnit_Framework_MockObject_MockObject $customer */ + /** + * @var CustomerInterface|MockObject $customer + */ $customer = $this->createMock(CustomerInterface::class); $customer->expects($this->any()) ->method('getWebsiteId') - ->willReturn($customerWebsiteId); + ->willReturn(self::STUB_CUSTOMER_WEBSITE_ID); $customer->expects($this->any()) ->method('getStoreId') ->willReturn($customerStoreId); $customer->expects($this->any()) ->method('getId') - ->willReturn($customerId); + ->willReturn(self::STUB_CUSTOMER_ID); $customer->expects($this->any()) ->method('getEmail') - ->willReturn($customerEmail); + ->willReturn(self::STUB_CUSTOMER_EMAIL); $this->storeMock->expects($this->any()) ->method('getId') ->willReturn($defaultStoreId); @@ -451,18 +544,18 @@ public function testPasswordReminderCustomerWithoutStoreId() ->method('getStore') ->with($defaultStoreId) ->willReturn($this->storeMock); - $websiteMock = $this->createPartialMock(\Magento\Store\Model\Website::class, ['getStoreIds']); + $websiteMock = $this->createPartialMock(Website::class, ['getStoreIds']); $websiteMock->expects($this->any()) ->method('getStoreIds') ->willReturn($storeIds); $this->storeManagerMock->expects($this->any()) ->method('getWebsite') - ->with($customerWebsiteId) + ->with(self::STUB_CUSTOMER_WEBSITE_ID) ->willReturn($websiteMock); $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') - ->with($customerId) + ->with(self::STUB_CUSTOMER_ID) ->willReturn($this->customerSecureMock); $this->dataProcessorMock->expects($this->once()) ->method('buildOutputDataArray') @@ -471,65 +564,76 @@ public function testPasswordReminderCustomerWithoutStoreId() $this->customerViewHelperMock->expects($this->any()) ->method('getCustomerName') ->with($customer) - ->willReturn($customerName); + ->willReturn(self::STUB_CUSTOMER_NAME); $this->customerSecureMock->expects($this->once()) ->method('addData') ->with($customerData) ->willReturnSelf(); $this->customerSecureMock->expects($this->once()) ->method('setData') - ->with('name', $customerName) + ->with('name', self::STUB_CUSTOMER_NAME) ->willReturnSelf(); $this->scopeConfigMock->expects($this->at(0)) ->method('getValue') - ->with(EmailNotification::XML_PATH_REMIND_EMAIL_TEMPLATE, ScopeInterface::SCOPE_STORE, $defaultStoreId) - ->willReturn($templateIdentifier); + ->with( + EmailNotification::XML_PATH_REMIND_EMAIL_TEMPLATE, + ScopeInterface::SCOPE_STORE, + $defaultStoreId + )->willReturn(self::STUB_EMAIL_IDENTIFIER); $this->scopeConfigMock->expects($this->at(1)) ->method('getValue') - ->with(EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, ScopeInterface::SCOPE_STORE, $defaultStoreId) - ->willReturn($sender); + ->with( + EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, + ScopeInterface::SCOPE_STORE, + $defaultStoreId + )->willReturn(self::STUB_SENDER); $this->mockDefaultTransportBuilder( - $templateIdentifier, + self::STUB_EMAIL_IDENTIFIER, $defaultStoreId, $senderValues, - $customerEmail, - $customerName, + self::STUB_CUSTOMER_EMAIL, + self::STUB_CUSTOMER_NAME, ['customer' => $this->customerSecureMock, 'store' => $this->storeMock] ); $this->model->passwordReminder($customer); } /** + * Test email notify for password reset confirm + * + * @dataProvider customerStoreIdDataProvider + * @param int $customerStoreId + * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testPasswordResetConfirmation() + public function testPasswordResetConfirmation($customerStoreId):void { - $customerId = 1; - $customerStoreId = 2; - $customerEmail = 'email@email.com'; $customerData = ['key' => 'value']; - $customerName = 'Customer Name'; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - $senderValues = ['name' => $sender, 'email' => $sender]; + $senderValues = ['name' => self::STUB_SENDER, 'email' => self::STUB_SENDER]; $this->senderResolverMock ->expects($this->once()) ->method('resolve') - ->with($sender, $customerStoreId) + ->with(self::STUB_SENDER, $customerStoreId) ->willReturn($senderValues); - /** @var CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ - $customer = $this->createMock(CustomerInterface::class); - $customer->expects($this->once()) + /** + * @var CustomerInterface|MockObject $customerMock + */ + $customerMock = $this->createMock(CustomerInterface::class); + + $customerMock->expects($this->never()) + ->method('getWebsiteId'); + + $customerMock->expects($this->once()) ->method('getStoreId') ->willReturn($customerStoreId); - $customer->expects($this->any()) + $customerMock->expects($this->any()) ->method('getId') - ->willReturn($customerId); - $customer->expects($this->any()) + ->willReturn(self::STUB_CUSTOMER_ID); + $customerMock->expects($this->any()) ->method('getEmail') - ->willReturn($customerEmail); + ->willReturn(self::STUB_CUSTOMER_EMAIL); $this->storeMock->expects($this->any()) ->method('getId') @@ -541,18 +645,18 @@ public function testPasswordResetConfirmation() $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') - ->with($customerId) + ->with(self::STUB_CUSTOMER_ID) ->willReturn($this->customerSecureMock); $this->dataProcessorMock->expects($this->once()) ->method('buildOutputDataArray') - ->with($customer, CustomerInterface::class) + ->with($customerMock, CustomerInterface::class) ->willReturn($customerData); $this->customerViewHelperMock->expects($this->any()) ->method('getCustomerName') - ->with($customer) - ->willReturn($customerName); + ->with($customerMock) + ->willReturn(self::STUB_CUSTOMER_NAME); $this->customerSecureMock->expects($this->once()) ->method('addData') @@ -560,61 +664,70 @@ public function testPasswordResetConfirmation() ->willReturnSelf(); $this->customerSecureMock->expects($this->once()) ->method('setData') - ->with('name', $customerName) + ->with('name', self::STUB_CUSTOMER_NAME) ->willReturnSelf(); $this->scopeConfigMock->expects($this->at(0)) ->method('getValue') - ->with(EmailNotification::XML_PATH_FORGOT_EMAIL_TEMPLATE, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($templateIdentifier); + ->with( + EmailNotification::XML_PATH_FORGOT_EMAIL_TEMPLATE, + ScopeInterface::SCOPE_STORE, + $customerStoreId + )->willReturn(self::STUB_EMAIL_IDENTIFIER); $this->scopeConfigMock->expects($this->at(1)) ->method('getValue') - ->with(EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($sender); + ->with( + EmailNotification::XML_PATH_FORGOT_EMAIL_IDENTITY, + ScopeInterface::SCOPE_STORE, + $customerStoreId + )->willReturn(self::STUB_SENDER); $this->mockDefaultTransportBuilder( - $templateIdentifier, + self::STUB_EMAIL_IDENTIFIER, $customerStoreId, $senderValues, - $customerEmail, - $customerName, + self::STUB_CUSTOMER_EMAIL, + self::STUB_CUSTOMER_NAME, ['customer' => $this->customerSecureMock, 'store' => $this->storeMock] ); - $this->model->passwordResetConfirmation($customer); + $this->model->passwordResetConfirmation($customerMock); } /** + * Test email notify with new account + * + * @dataProvider customerStoreIdDataProvider + * @param int $customerStoreId + * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testNewAccount() + public function testNewAccount($customerStoreId):void { - $customerId = 1; - $customerStoreId = 2; - $customerEmail = 'email@email.com'; $customerData = ['key' => 'value']; - $customerName = 'Customer Name'; - $templateIdentifier = 'Template Identifier'; - $sender = 'Sender'; - $senderValues = ['name' => $sender, 'email' => $sender]; + $senderValues = ['name' => self::STUB_SENDER, 'email' => self::STUB_SENDER]; $this->senderResolverMock ->expects($this->once()) ->method('resolve') - ->with($sender, $customerStoreId) + ->with(self::STUB_SENDER, $customerStoreId) ->willReturn($senderValues); - /** @var CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ + /** + * @var CustomerInterface|MockObject $customer + */ $customer = $this->createMock(CustomerInterface::class); + $customer->expects($this->never()) + ->method('getWebsiteId'); $customer->expects($this->any()) ->method('getStoreId') ->willReturn($customerStoreId); $customer->expects($this->any()) ->method('getId') - ->willReturn($customerId); + ->willReturn(self::STUB_CUSTOMER_ID); $customer->expects($this->any()) ->method('getEmail') - ->willReturn($customerEmail); + ->willReturn(self::STUB_CUSTOMER_EMAIL); $this->storeMock->expects($this->any()) ->method('getId') @@ -627,7 +740,7 @@ public function testNewAccount() $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') - ->with($customerId) + ->with(self::STUB_CUSTOMER_ID) ->willReturn($this->customerSecureMock); $this->dataProcessorMock->expects($this->once()) @@ -638,7 +751,7 @@ public function testNewAccount() $this->customerViewHelperMock->expects($this->any()) ->method('getCustomerName') ->with($customer) - ->willReturn($customerName); + ->willReturn(self::STUB_CUSTOMER_NAME); $this->customerSecureMock->expects($this->once()) ->method('addData') @@ -646,28 +759,52 @@ public function testNewAccount() ->willReturnSelf(); $this->customerSecureMock->expects($this->once()) ->method('setData') - ->with('name', $customerName) + ->with('name', self::STUB_CUSTOMER_NAME) ->willReturnSelf(); $this->scopeConfigMock->expects($this->at(0)) ->method('getValue') - ->with(EmailNotification::XML_PATH_REGISTER_EMAIL_TEMPLATE, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($templateIdentifier); + ->with( + EmailNotification::XML_PATH_REGISTER_EMAIL_TEMPLATE, + ScopeInterface::SCOPE_STORE, + $customerStoreId + )->willReturn(self::STUB_EMAIL_IDENTIFIER); $this->scopeConfigMock->expects($this->at(1)) ->method('getValue') - ->with(EmailNotification::XML_PATH_REGISTER_EMAIL_IDENTITY, ScopeInterface::SCOPE_STORE, $customerStoreId) - ->willReturn($sender); + ->with( + EmailNotification::XML_PATH_REGISTER_EMAIL_IDENTITY, + ScopeInterface::SCOPE_STORE, + $customerStoreId + )->willReturn(self::STUB_SENDER); $this->mockDefaultTransportBuilder( - $templateIdentifier, + self::STUB_EMAIL_IDENTIFIER, $customerStoreId, $senderValues, - $customerEmail, - $customerName, + self::STUB_CUSTOMER_EMAIL, + self::STUB_CUSTOMER_NAME, ['customer' => $this->customerSecureMock, 'back_url' => '', 'store' => $this->storeMock] ); - $this->model->newAccount($customer, EmailNotification::NEW_ACCOUNT_EMAIL_REGISTERED, '', $customerStoreId); + $this->model->newAccount( + $customer, + EmailNotification::NEW_ACCOUNT_EMAIL_REGISTERED, + '', + $customerStoreId + ); + } + + /** + * DataProvider customer store + * + * @return array + */ + public function customerStoreIdDataProvider():array + { + return [ + ['customerStoreId' => 0], + ['customerStoreId' => 2] + ]; } /** @@ -689,8 +826,8 @@ private function mockDefaultTransportBuilder( string $customerEmail, string $customerName, array $templateVars = [] - ): void { - $transport = $this->createMock(\Magento\Framework\Mail\TransportInterface::class); + ):void { + $transportMock = $this->createMock(TransportInterface::class); $this->transportBuilderMock->expects($this->once()) ->method('setTemplateIdentifier') @@ -714,9 +851,9 @@ private function mockDefaultTransportBuilder( ->willReturnSelf(); $this->transportBuilderMock->expects($this->once()) ->method('getTransport') - ->willReturn($transport); + ->willReturn($transportMock); - $transport->expects($this->once()) + $transportMock->expects($this->once()) ->method('sendMessage'); } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Customer/Test/Unit/Model/Layout/DepersonalizePluginTest.php index 15337d8968305..095a83101322f 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -3,143 +3,177 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Customer\Test\Unit\Model\Layout; +use Magento\Customer\Model\Customer; +use Magento\Customer\Model\CustomerFactory; +use Magento\Customer\Model\Layout\DepersonalizePlugin; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Customer\Model\Visitor as VisitorModel; +use Magento\Framework\Data\Form\FormKey; +use Magento\Framework\Session\Generic as GenericSession; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\LayoutInterface; +use Magento\PageCache\Model\DepersonalizeChecker; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + /** - * Class DepersonalizePluginTest + * Unit tests for \Magento\Customer\Model\Layout\DepersonalizePlugin class. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class DepersonalizePluginTest extends \PHPUnit\Framework\TestCase +class DepersonalizePluginTest extends TestCase { /** - * @var \Magento\Customer\Model\Layout\DepersonalizePlugin + * @var DepersonalizePlugin */ - protected $plugin; + private $plugin; /** - * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject + * @var LayoutInterface|MockObject */ - protected $layoutMock; + private $layoutMock; /** - * @var \Magento\Framework\Session\Generic|\PHPUnit_Framework_MockObject_MockObject + * @var GenericSession|MockObject */ - protected $sessionMock; + private $sessionMock; /** - * @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject + * @var CustomerSession|MockObject */ - protected $customerSessionMock; + private $customerSessionMock; /** - * @var \Magento\Customer\Model\CustomerFactory|\PHPUnit_Framework_MockObject_MockObject + * @var CustomerFactory|MockObject */ - protected $customerFactoryMock; + private $customerFactoryMock; /** - * @var \Magento\Customer\Model\Customer|\PHPUnit_Framework_MockObject_MockObject + * @var Customer|MockObject */ - protected $customerMock; + private $customerMock; /** - * @var \Magento\Customer\Model\Visitor|\PHPUnit_Framework_MockObject_MockObject + * @var VisitorModel|MockObject */ - protected $visitorMock; + private $visitorMock; /** - * @var \Magento\PageCache\Model\DepersonalizeChecker|\PHPUnit_Framework_MockObject_MockObject + * @var DepersonalizeChecker|MockObject */ - protected $depersonalizeCheckerMock; + private $depersonalizeCheckerMock; /** - * SetUp + * @inheritdoc */ protected function setUp() { - $this->layoutMock = $this->createMock(\Magento\Framework\View\Layout::class); + $this->layoutMock = $this->getMockForAbstractClass(LayoutInterface::class); $this->sessionMock = $this->createPartialMock( - \Magento\Framework\Session\Generic::class, + GenericSession::class, ['clearStorage', 'setData', 'getData'] ); $this->customerSessionMock = $this->createPartialMock( - \Magento\Customer\Model\Session::class, + CustomerSession::class, ['getCustomerGroupId', 'setCustomerGroupId', 'clearStorage', 'setCustomer'] ); - $this->customerFactoryMock = $this->createPartialMock( - \Magento\Customer\Model\CustomerFactory::class, - ['create'] - ); + $this->customerFactoryMock = $this->createPartialMock(CustomerFactory::class, ['create']); $this->customerMock = $this->createPartialMock( - \Magento\Customer\Model\Customer::class, + Customer::class, ['setGroupId', '__wakeup'] ); - $this->visitorMock = $this->createMock(\Magento\Customer\Model\Visitor::class); + $this->visitorMock = $this->createMock(VisitorModel::class); $this->customerFactoryMock->expects($this->any()) ->method('create') - ->will($this->returnValue($this->customerMock)); - $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); - - $this->plugin = new \Magento\Customer\Model\Layout\DepersonalizePlugin( - $this->depersonalizeCheckerMock, - $this->sessionMock, - $this->customerSessionMock, - $this->customerFactoryMock, - $this->visitorMock + ->willReturn($this->customerMock); + $this->depersonalizeCheckerMock = $this->createMock(DepersonalizeChecker::class); + + $this->plugin = (new ObjectManagerHelper($this))->getObject( + DepersonalizePlugin::class, + [ + 'depersonalizeChecker' => $this->depersonalizeCheckerMock, + 'session' => $this->sessionMock, + 'customerSession' => $this->customerSessionMock, + 'customerFactory' => $this->customerFactoryMock, + 'visitor' => $this->visitorMock, + ] ); } - public function testBeforeGenerateXml() + /** + * Test beforeGenerateXml method when depersonalization is needed. + * + * @return void + */ + public function testBeforeGenerateXml(): void { $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); $this->customerSessionMock->expects($this->once())->method('getCustomerGroupId'); $this->sessionMock ->expects($this->once()) ->method('getData') - ->with($this->equalTo(\Magento\Framework\Data\Form\FormKey::FORM_KEY)); - $output = $this->plugin->beforeGenerateXml($this->layoutMock); - $this->assertEquals([], $output); + ->with($this->equalTo(FormKey::FORM_KEY)); + $this->plugin->beforeGenerateXml($this->layoutMock); } - public function testBeforeGenerateXmlNoDepersonalize() + /** + * Test beforeGenerateXml method when depersonalization is not needed. + * + * @return void + */ + public function testBeforeGenerateXmlNoDepersonalize(): void { $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); $this->customerSessionMock->expects($this->never())->method('getCustomerGroupId'); $this->sessionMock ->expects($this->never()) ->method('getData'); - $output = $this->plugin->beforeGenerateXml($this->layoutMock); - $this->assertEquals([], $output); + $this->plugin->beforeGenerateXml($this->layoutMock); } - public function testAfterGenerateXml() + /** + * Test afterGenerateElements method when depersonalization is needed. + * + * @return void + */ + public function testAfterGenerateElements(): void { - $expectedResult = $this->createMock(\Magento\Framework\View\Layout::class); $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); $this->visitorMock->expects($this->once())->method('setSkipRequestLogging')->with($this->equalTo(true)); $this->visitorMock->expects($this->once())->method('unsetData'); $this->sessionMock->expects($this->once())->method('clearStorage'); $this->customerSessionMock->expects($this->once())->method('clearStorage'); $this->customerSessionMock->expects($this->once())->method('setCustomerGroupId')->with($this->equalTo(null)); - $this->customerMock->expects($this->once())->method('setGroupId')->with($this->equalTo(null))->willReturnSelf(); + $this->customerMock + ->expects($this->once()) + ->method('setGroupId') + ->with($this->equalTo(null)) + ->willReturnSelf(); $this->sessionMock ->expects($this->once()) ->method('setData') ->with( - $this->equalTo(\Magento\Framework\Data\Form\FormKey::FORM_KEY), + $this->equalTo(FormKey::FORM_KEY), $this->equalTo(null) ); $this->customerSessionMock ->expects($this->once()) ->method('setCustomer') ->with($this->equalTo($this->customerMock)); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $expectedResult); - $this->assertSame($expectedResult, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } - public function testAfterGenerateXmlNoDepersonalize() + /** + * Test afterGenerateElements method when depersonalization is not needed. + * + * @return void + */ + public function testAfterGenerateElementsNoDepersonalize(): void { - $expectedResult = $this->createMock(\Magento\Framework\View\Layout::class); $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); $this->visitorMock->expects($this->never())->method('setSkipRequestLogging'); $this->visitorMock->expects($this->never())->method('unsetData'); @@ -149,7 +183,6 @@ public function testAfterGenerateXmlNoDepersonalize() $this->customerMock->expects($this->never())->method('setGroupId'); $this->sessionMock->expects($this->never())->method('setData'); $this->customerSessionMock->expects($this->never())->method('setCustomer'); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $expectedResult); - $this->assertSame($expectedResult, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } } diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/ColumnFactoryTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/ColumnFactoryTest.php index d917cc4908ac8..8b926e8dfdec8 100644 --- a/app/code/Magento/Customer/Test/Unit/Ui/Component/ColumnFactoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/ColumnFactoryTest.php @@ -6,28 +6,29 @@ namespace Magento\Customer\Test\Unit\Ui\Component; use Magento\Customer\Ui\Component\ColumnFactory; +use PHPUnit\Framework\MockObject\MockObject; /** * Test ColumnFactory Class */ class ColumnFactoryTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Customer\Api\Data\OptionInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Customer\Api\Data\OptionInterface|MockObject */ protected $attributeOption; - /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|MockObject */ protected $context; - /** @var \Magento\Framework\View\Element\UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponentFactory|MockObject */ protected $componentFactory; - /** @var \Magento\Customer\Api\Data\AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Customer\Api\Data\AttributeMetadataInterface|MockObject */ protected $attributeMetadata; - /** @var \Magento\Ui\Component\Listing\Columns\ColumnInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Ui\Component\Listing\Columns\ColumnInterface|MockObject */ protected $column; - /** @var \Magento\Customer\Ui\Component\Listing\Column\InlineEditUpdater|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Customer\Ui\Component\Listing\Column\InlineEditUpdater|MockObject */ protected $inlineEditUpdater; /** @var ColumnFactory */ @@ -93,7 +94,6 @@ public function testCreate() ] ], 'component' => 'Magento_Ui/js/grid/columns/column', - '__disableTmpl' => 'true' ], ], 'context' => $this->context, diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/FilterFactoryTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/FilterFactoryTest.php index f3c0a56262622..3a23cf66faddc 100644 --- a/app/code/Magento/Customer/Test/Unit/Ui/Component/FilterFactoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/FilterFactoryTest.php @@ -6,25 +6,26 @@ namespace Magento\Customer\Test\Unit\Ui\Component; use Magento\Customer\Ui\Component\FilterFactory; +use PHPUnit\Framework\MockObject\MockObject; /** * Test FilterFactory Class */ class FilterFactoryTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Customer\Api\Data\OptionInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Customer\Api\Data\OptionInterface|MockObject */ protected $attributeOption; - /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|MockObject */ protected $context; - /** @var \Magento\Framework\View\Element\UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponentFactory|MockObject */ protected $componentFactory; - /** @var \Magento\Customer\Api\Data\AttributeMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Customer\Api\Data\AttributeMetadataInterface|MockObject */ protected $attributeMetadata; - /** @var \Magento\Ui\Component\Listing\Columns\ColumnInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Ui\Component\Listing\Columns\ColumnInterface|MockObject */ protected $filter; /** @var FilterFactory */ @@ -72,7 +73,6 @@ public function testCreate() 'config' => [ 'dataScope' => $filterName, 'label' => __('Label'), - '__disableTmpl' => 'true', 'options' => [['value' => 'Value', 'label' => 'Label']], 'caption' => __('Select...'), ], diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php index 4a16acd98d827..3792f0d214537 100644 --- a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php +++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php @@ -6,22 +6,23 @@ namespace Magento\Customer\Test\Unit\Ui\Component\Listing\Column; use Magento\Customer\Ui\Component\Listing\Column\Actions; +use PHPUnit\Framework\MockObject\MockObject; /** - * Class ActionsTest + * Class Actions test for Listing Colummn */ class ActionsTest extends \PHPUnit\Framework\TestCase { /** @var Actions */ protected $component; - /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|MockObject */ protected $context; - /** @var \Magento\Framework\View\Element\UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponentFactory|MockObject */ protected $uiComponentFactory; - /** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\UrlInterface|MockObject */ protected $urlBuilder; public function setup() @@ -68,7 +69,6 @@ public function testPrepareDataSource() 'href' => 'http://magento.com/customer/index/edit', 'label' => new \Magento\Framework\Phrase('Edit'), 'hidden' => false, - '__disableTmpl' => true, ] ] ], diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/GroupActionsTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/GroupActionsTest.php index 02cacea5c2601..deec8ab7f7281 100644 --- a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/GroupActionsTest.php +++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/GroupActionsTest.php @@ -202,7 +202,6 @@ public function testPrepareDataSourceWithDefaultGroup() 'edit' => [ 'href' => static::STUB_GROUP_EDIT_URL, 'label' => __('Edit'), - '__disableTmpl' => true, ] ] ], @@ -213,7 +212,6 @@ public function testPrepareDataSourceWithDefaultGroup() 'edit' => [ 'href' => static::STUB_GROUP_EDIT_URL, 'label' => __('Edit'), - '__disableTmpl' => true, ] ] ] @@ -289,13 +287,11 @@ public function customerGroupsDataProvider(): array 'edit' => [ 'href' => static::STUB_GROUP_EDIT_URL, 'label' => __('Edit'), - '__disableTmpl' => true, ], 'delete' => [ 'href' => static::STUB_GROUP_DELETE_URL, 'label' => __('Delete'), 'post' => true, - '__disableTmpl' => true, 'confirm' => [ 'title' => __('Delete %1', 'General'), 'message' => __( diff --git a/app/code/Magento/Customer/Ui/Component/ColumnFactory.php b/app/code/Magento/Customer/Ui/Component/ColumnFactory.php index a69e84ab41a2c..22f1a3315595b 100644 --- a/app/code/Magento/Customer/Ui/Component/ColumnFactory.php +++ b/app/code/Magento/Customer/Ui/Component/ColumnFactory.php @@ -77,7 +77,6 @@ public function create(array $attributeData, $columnName, $context, array $confi 'component' => $this->getJsComponent( $this->getDataType($attributeData[AttributeMetadata::FRONTEND_INPUT]) ), - '__disableTmpl' => 'true' ], $config ); diff --git a/app/code/Magento/Customer/Ui/Component/FilterFactory.php b/app/code/Magento/Customer/Ui/Component/FilterFactory.php index 3e57db06246d4..7575062dd23db 100644 --- a/app/code/Magento/Customer/Ui/Component/FilterFactory.php +++ b/app/code/Magento/Customer/Ui/Component/FilterFactory.php @@ -48,7 +48,6 @@ public function create(array $attributeData, $context) $config = [ 'dataScope' => $attributeData[AttributeMetadata::ATTRIBUTE_CODE], 'label' => __($attributeData[AttributeMetadata::FRONTEND_LABEL]), - '__disableTmpl' => 'true' ]; if ($attributeData[AttributeMetadata::OPTIONS]) { $config['options'] = $attributeData[AttributeMetadata::OPTIONS]; diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php index 9441beeb7dc61..d6a4067ef3db6 100644 --- a/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php +++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php @@ -60,7 +60,6 @@ public function prepareDataSource(array $dataSource) ), 'label' => __('Edit'), 'hidden' => false, - '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php index e5a536dc6ecd6..459ac3e29e993 100644 --- a/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php +++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php @@ -96,7 +96,6 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Edit'), - '__disableTmpl' => true ], ]; @@ -117,7 +116,6 @@ public function prepareDataSource(array $dataSource) ) ], 'post' => true, - '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Customer/Ui/Component/MassAction/Group/Options.php b/app/code/Magento/Customer/Ui/Component/MassAction/Group/Options.php index e5739317bca8d..16caf346c808c 100644 --- a/app/code/Magento/Customer/Ui/Component/MassAction/Group/Options.php +++ b/app/code/Magento/Customer/Ui/Component/MassAction/Group/Options.php @@ -10,7 +10,9 @@ use Magento\Customer\Model\ResourceModel\Group\CollectionFactory; /** - * Class Options + * Class Options for Mass Action Group + * + * Disable template needed for customers */ class Options implements \JsonSerializable { diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 60a2da9d6dfa7..ba0bb3bac6a98 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -357,6 +357,11 @@ <type name="Magento\Framework\App\ActionInterface"> <plugin name="customerNotification" type="Magento\Customer\Model\Plugin\CustomerNotification"/> </type> + <type name="Magento\Customer\Model\Authorization\CustomerSessionUserContext"> + <arguments> + <argument name="customerSession" xsi:type="object">Magento\Customer\Model\Session\Proxy</argument> + </arguments> + </type> <type name="Magento\PageCache\Observer\FlushFormKey"> <plugin name="customerFlushFormKey" type="Magento\Customer\Model\Plugin\CustomerFlushFormKey"/> </type> diff --git a/app/code/Magento/Customer/view/frontend/email/change_email.html b/app/code/Magento/Customer/view/frontend/email/change_email.html index 4853adf638066..bd961ad99ec40 100644 --- a/app/code/Magento/Customer/view/frontend/email/change_email.html +++ b/app/code/Magento/Customer/view/frontend/email/change_email.html @@ -8,13 +8,12 @@ <!--@vars { "var store.frontend_name":"Store Name", "var store_email":"Store Email", -"var store_phone":"Store Phone" +"var store_phone":"Store Phone", +"var customer.name":"Customer Name" } @--> {{template config_path="design/email/header_template"}} -<p class="greeting">{{trans "Hello,"}}</p> -<br> - +<p class="greeting">{{trans "%name," name=$customer.name}}</p> <p> {{trans "We have received a request to change the following information associated with your account at %store_name: email." store_name=$store.frontend_name}} {{trans 'If you have not authorized this action, please contact us immediately at <a href="mailto:%store_email">%store_email</a>' store_email=$store_email |raw}}{{depend store_phone}} {{trans 'or call us at <a href="tel:%store_phone">%store_phone</a>' store_phone=$store_phone |raw}}{{/depend}}. diff --git a/app/code/Magento/Customer/view/frontend/email/change_email_and_password.html b/app/code/Magento/Customer/view/frontend/email/change_email_and_password.html index 49867bdedc9e0..4f5c85b2381f3 100644 --- a/app/code/Magento/Customer/view/frontend/email/change_email_and_password.html +++ b/app/code/Magento/Customer/view/frontend/email/change_email_and_password.html @@ -8,13 +8,12 @@ <!--@vars { "var store.frontend_name":"Store Name", "var store_email":"Store Email", -"var store_phone":"Store Phone" +"var store_phone":"Store Phone", +"var customer.name":"Customer Name" } @--> {{template config_path="design/email/header_template"}} -<p class="greeting">{{trans "Hello,"}}</p> -<br> - +<p class="greeting">{{trans "%name," name=$customer.name}}</p> <p> {{trans "We have received a request to change the following information associated with your account at %store_name: email, password." store_name=$store.frontend_name}} {{trans 'If you have not authorized this action, please contact us immediately at <a href="mailto:%store_email">%store_email</a>' store_email=$store_email |raw}}{{depend store_phone}} {{trans 'or call us at <a href="tel:%store_phone">%store_phone</a>' store_phone=$store_phone |raw}}{{/depend}}. diff --git a/app/code/Magento/Customer/view/frontend/email/password_reset.html b/app/code/Magento/Customer/view/frontend/email/password_reset.html index 79015117c2280..cab05a89227b6 100644 --- a/app/code/Magento/Customer/view/frontend/email/password_reset.html +++ b/app/code/Magento/Customer/view/frontend/email/password_reset.html @@ -9,13 +9,12 @@ "var customer.name":"Customer Name", "var store.frontend_name":"Store Name", "var store_email":"Store Email", -"var store_phone":"Store Phone" +"var store_phone":"Store Phone", +"var customer.name":"Customer Name" } @--> {{template config_path="design/email/header_template"}} -<p class="greeting">{{trans "Hello,"}}</p> -<br> - +<p class="greeting">{{trans "%name," name=$customer.name}}</p> <p> {{trans "We have received a request to change the following information associated with your account at %store_name: password." store_name=$store.frontend_name}} {{trans 'If you have not authorized this action, please contact us immediately at <a href="mailto:%store_email">%store_email</a>' store_email=$store_email |raw}}{{depend store_phone}} {{trans 'or call us at <a href="tel:%store_phone">%store_phone</a>' store_phone=$store_phone |raw}}{{/depend}}. diff --git a/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php b/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php index 78531c7e6c22c..5800f7162b7f0 100644 --- a/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php +++ b/app/code/Magento/Developer/Console/Command/GeneratePatchCommand.php @@ -7,13 +7,12 @@ namespace Magento\Developer\Console\Command; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Component\ComponentRegistrar; use Magento\Framework\Console\Cli; use Magento\Framework\Exception\FileSystemException; -use Magento\Framework\Filesystem\DirectoryList; use Magento\Framework\Filesystem\Directory\ReadFactory; use Magento\Framework\Filesystem\Directory\WriteFactory; +use Magento\Framework\Filesystem\DirectoryList; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -58,20 +57,20 @@ class GeneratePatchCommand extends Command * GeneratePatchCommand constructor. * * @param ComponentRegistrar $componentRegistrar - * @param DirectoryList|null $directoryList - * @param ReadFactory|null $readFactory - * @param WriteFactory|null $writeFactory + * @param DirectoryList $directoryList + * @param ReadFactory $readFactory + * @param WriteFactory $writeFactory */ public function __construct( ComponentRegistrar $componentRegistrar, - DirectoryList $directoryList = null, - ReadFactory $readFactory = null, - WriteFactory $writeFactory = null + DirectoryList $directoryList, + ReadFactory $readFactory, + WriteFactory $writeFactory ) { $this->componentRegistrar = $componentRegistrar; - $this->directoryList = $directoryList ?: ObjectManager::getInstance()->get(DirectoryList::class); - $this->readFactory = $readFactory ?: ObjectManager::getInstance()->get(ReadFactory::class); - $this->writeFactory = $writeFactory ?: ObjectManager::getInstance()->get(WriteFactory::class); + $this->directoryList = $directoryList; + $this->readFactory = $readFactory; + $this->writeFactory = $writeFactory; parent::__construct(); } @@ -120,6 +119,7 @@ protected function configure() * * @param InputInterface $input * @param OutputInterface $output + * * @return int * @throws FileSystemException */ @@ -194,8 +194,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int private function getPatchTemplate(): string { $read = $this->readFactory->create(__DIR__ . '/'); - $content = $read->readFile('patch_template.php.dist'); - return $content; + return $read->readFile('patch_template.php.dist'); } /** @@ -207,7 +206,6 @@ private function getPatchTemplate(): string private function getRevertMethodTemplate(): string { $read = $this->readFactory->create(__DIR__ . '/'); - $content = $read->readFile('template_revert_function.php.dist'); - return $content; + return $read->readFile('template_revert_function.php.dist'); } } diff --git a/app/code/Magento/Developer/Model/Css/PreProcessor/FileGenerator/PublicationDecorator.php b/app/code/Magento/Developer/Model/Css/PreProcessor/FileGenerator/PublicationDecorator.php index 1b2a0986fa0ad..10474d8455b1b 100644 --- a/app/code/Magento/Developer/Model/Css/PreProcessor/FileGenerator/PublicationDecorator.php +++ b/app/code/Magento/Developer/Model/Css/PreProcessor/FileGenerator/PublicationDecorator.php @@ -3,11 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Developer\Model\Css\PreProcessor\FileGenerator; use Magento\Developer\Model\Config\Source\WorkflowType; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\App\ObjectManager; use Magento\Framework\App\State; use Magento\Framework\App\View\Asset\Publisher; use Magento\Framework\Css\PreProcessor\File\Temporary; @@ -31,22 +32,21 @@ class PublicationDecorator extends RelatedGenerator private $scopeConfig; /** - * @var bool + * @var State */ - private $hasRelatedPublishing; + private $state; /** - * @var State + * @var bool */ - private $state; + private $hasRelatedPublishing; /** - * Constructor - * * @param Repository $assetRepository * @param Temporary $temporaryFile * @param Publisher $assetPublisher * @param ScopeConfigInterface $scopeConfig + * @param State $state * @param bool $hasRelatedPublishing */ public function __construct( @@ -54,11 +54,13 @@ public function __construct( Temporary $temporaryFile, Publisher $assetPublisher, ScopeConfigInterface $scopeConfig, + State $state, $hasRelatedPublishing = false ) { parent::__construct($assetRepository, $temporaryFile); $this->assetPublisher = $assetPublisher; $this->scopeConfig = $scopeConfig; + $this->state = $state; $this->hasRelatedPublishing = $hasRelatedPublishing; } @@ -69,7 +71,7 @@ protected function generateRelatedFile($relatedFileId, LocalInterface $asset) { $relatedAsset = parent::generateRelatedFile($relatedFileId, $asset); $isClientSideCompilation = - $this->getState()->getMode() !== State::MODE_PRODUCTION + $this->state->getMode() !== State::MODE_PRODUCTION && WorkflowType::CLIENT_SIDE_COMPILATION === $this->scopeConfig->getValue(WorkflowType::CONFIG_NAME_PATH); if ($this->hasRelatedPublishing || $isClientSideCompilation) { @@ -78,17 +80,4 @@ protected function generateRelatedFile($relatedFileId, LocalInterface $asset) return $relatedAsset; } - - /** - * @return State - * @deprecated 100.2.0 - */ - private function getState() - { - if (null === $this->state) { - $this->state = ObjectManager::getInstance()->get(State::class); - } - - return $this->state; - } } diff --git a/app/code/Magento/Developer/Model/TemplateEngine/Plugin/DebugHints.php b/app/code/Magento/Developer/Model/TemplateEngine/Plugin/DebugHints.php index a10d7bca1b89e..07eb1257f9561 100644 --- a/app/code/Magento/Developer/Model/TemplateEngine/Plugin/DebugHints.php +++ b/app/code/Magento/Developer/Model/TemplateEngine/Plugin/DebugHints.php @@ -1,7 +1,5 @@ <?php /** - * Plugin for the template engine factory that makes a decision of whether to activate debugging hints or not - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -16,6 +14,9 @@ use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Request\Http; +/** + * Plugin for the template engine factory that makes a decision of whether to activate debugging hints or not + */ class DebugHints { /** @@ -26,22 +27,27 @@ class DebugHints /** * @var ScopeConfigInterface */ - protected $scopeConfig; + private $scopeConfig; /** * @var StoreManagerInterface */ - protected $storeManager; + private $storeManager; /** * @var DevHelper */ - protected $devHelper; + private $devHelper; /** * @var DebugHintsFactory */ - protected $debugHintsFactory; + private $debugHintsFactory; + + /** + * @var Http + */ + private $http; /** * XPath of configuration of the debug hints @@ -52,7 +58,7 @@ class DebugHints * * @var string */ - protected $debugHintsPath; + private $debugHintsPath; /** * XPath of configuration of the debug hints show with parameter @@ -77,8 +83,8 @@ class DebugHints * @param StoreManagerInterface $storeManager * @param DevHelper $devHelper * @param DebugHintsFactory $debugHintsFactory - * @param string $debugHintsPath * @param Http $http + * @param string $debugHintsPath * @param string $debugHintsWithParam * @param string $debugHintsParameter */ @@ -87,8 +93,8 @@ public function __construct( StoreManagerInterface $storeManager, DevHelper $devHelper, DebugHintsFactory $debugHintsFactory, + Http $http, $debugHintsPath, - Http $http = null, $debugHintsWithParam = null, $debugHintsParameter = null ) { @@ -96,10 +102,8 @@ public function __construct( $this->storeManager = $storeManager; $this->devHelper = $devHelper; $this->debugHintsFactory = $debugHintsFactory; + $this->http = $http; $this->debugHintsPath = $debugHintsPath; - $this->http = $http ?: \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\App\Request\Http::class - ); $this->debugHintsWithParam = $debugHintsWithParam; $this->debugHintsParameter = $debugHintsParameter; } @@ -152,6 +156,7 @@ public function afterCreate( ]); } } + return $invocationResult; } } diff --git a/app/code/Magento/Developer/Model/View/Asset/PreProcessor/PreprocessorStrategy.php b/app/code/Magento/Developer/Model/View/Asset/PreProcessor/PreprocessorStrategy.php index 6e230d351a25f..fac74a9e2d2bd 100644 --- a/app/code/Magento/Developer/Model/View/Asset/PreProcessor/PreprocessorStrategy.php +++ b/app/code/Magento/Developer/Model/View/Asset/PreProcessor/PreprocessorStrategy.php @@ -42,32 +42,34 @@ class PreprocessorStrategy implements PreProcessorInterface private $state; /** - * Constructor - * * @param AlternativeSourceInterface $alternativeSource * @param FrontendCompilation $frontendCompilation * @param ScopeConfigInterface $scopeConfig + * @param State|null $state */ public function __construct( AlternativeSourceInterface $alternativeSource, FrontendCompilation $frontendCompilation, - ScopeConfigInterface $scopeConfig + ScopeConfigInterface $scopeConfig, + ?State $state = null ) { $this->frontendCompilation = $frontendCompilation; $this->alternativeSource = $alternativeSource; $this->scopeConfig = $scopeConfig; + $this->state = $state ?? ObjectManager::getInstance()->get(State::class); } /** * Transform content and/or content type for the specified pre-processing chain object * * @param PreProcessor\Chain $chain + * * @return void */ public function process(PreProcessor\Chain $chain) { $isClientSideCompilation = - $this->getState()->getMode() !== State::MODE_PRODUCTION + $this->state->getMode() !== State::MODE_PRODUCTION && WorkflowType::CLIENT_SIDE_COMPILATION === $this->scopeConfig->getValue(WorkflowType::CONFIG_NAME_PATH); if ($isClientSideCompilation) { @@ -76,16 +78,4 @@ public function process(PreProcessor\Chain $chain) $this->alternativeSource->process($chain); } } - - /** - * @return State - * @deprecated 100.2.0 - */ - private function getState() - { - if (null === $this->state) { - $this->state = ObjectManager::getInstance()->get(State::class); - } - return $this->state; - } } diff --git a/app/code/Magento/Developer/Model/XmlCatalog/Format/PhpStorm.php b/app/code/Magento/Developer/Model/XmlCatalog/Format/PhpStorm.php index aef58a9a37e89..2e780d37bdf85 100644 --- a/app/code/Magento/Developer/Model/XmlCatalog/Format/PhpStorm.php +++ b/app/code/Magento/Developer/Model/XmlCatalog/Format/PhpStorm.php @@ -3,14 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Developer\Model\XmlCatalog\Format; -use Magento\Framework\App\ObjectManager; use Magento\Framework\DomDocument\DomDocumentFactory; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Filesystem\Directory\ReadFactory; use Magento\Framework\Filesystem\Directory\ReadInterface; +use Magento\Framework\Filesystem\DriverPool; use Magento\Framework\Filesystem\File\WriteFactory; /** @@ -43,11 +44,11 @@ class PhpStorm implements FormatInterface public function __construct( ReadFactory $readFactory, WriteFactory $fileWriteFactory, - DomDocumentFactory $domDocumentFactory = null + DomDocumentFactory $domDocumentFactory ) { $this->currentDirRead = $readFactory->create(getcwd()); $this->fileWriteFactory = $fileWriteFactory; - $this->domDocumentFactory = $domDocumentFactory ?: ObjectManager::getInstance()->get(DomDocumentFactory::class); + $this->domDocumentFactory = $domDocumentFactory; } /** @@ -55,6 +56,7 @@ public function __construct( * * @param string[] $dictionary * @param string $configFilePath relative path to the PhpStorm misc.xml + * * @return void */ public function generateCatalog(array $dictionary, $configFilePath) @@ -65,7 +67,7 @@ public function generateCatalog(array $dictionary, $configFilePath) try { $file = $this->fileWriteFactory->create( $configFilePath, - \Magento\Framework\Filesystem\DriverPool::FILE, + DriverPool::FILE, 'r' ); $dom = $this->domDocumentFactory->create(); @@ -103,7 +105,7 @@ public function generateCatalog(array $dictionary, $configFilePath) $dom->formatOutput = true; $file = $this->fileWriteFactory->create( $configFilePath, - \Magento\Framework\Filesystem\DriverPool::FILE, + DriverPool::FILE, 'w' ); $file->write($dom->saveXML()); diff --git a/app/code/Magento/Developer/Test/Unit/Model/TemplateEngine/Plugin/DebugHintsTest.php b/app/code/Magento/Developer/Test/Unit/Model/TemplateEngine/Plugin/DebugHintsTest.php index a918a562a926d..d7ab4fdea2c37 100644 --- a/app/code/Magento/Developer/Test/Unit/Model/TemplateEngine/Plugin/DebugHintsTest.php +++ b/app/code/Magento/Developer/Test/Unit/Model/TemplateEngine/Plugin/DebugHintsTest.php @@ -3,60 +3,103 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Developer\Test\Unit\Model\TemplateEngine\Plugin; +use Magento\Developer\Helper\Data; +use Magento\Developer\Model\TemplateEngine\Decorator\DebugHints as DebugHintsDecorator; use Magento\Developer\Model\TemplateEngine\Decorator\DebugHintsFactory; use Magento\Developer\Model\TemplateEngine\Plugin\DebugHints; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Request\Http; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\TemplateEngineFactory; +use Magento\Framework\View\TemplateEngineInterface; +use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class DebugHintsTest extends \PHPUnit\Framework\TestCase +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class DebugHintsTest extends TestCase { + private const STORE_CODE = 'default'; + + /** + * @var ObjectManager + */ + private $objectManager; + /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ - protected $scopeConfigMock; + private $scopeConfigMock; /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var StoreManagerInterface|MockObject */ - protected $storeManager; + private $storeManagerMock; /** - * @var \Magento\Developer\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + * @var Data|MockObject */ - protected $devHelperMock; + private $devHelperMock; /** - * @var DebugHintsFactory | \PHPUnit_Framework_MockObject_MockObject + * @var DebugHintsFactory|MockObject */ - protected $debugHintsFactory; + private $debugHintsFactoryMock; + + /** + * @var Http|MockObject + */ + private $httpMock; /** * @return void */ protected function setUp() { - $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class) ->getMockForAbstractClass(); - $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) ->getMockForAbstractClass(); - $this->devHelperMock = $this->getMockBuilder(\Magento\Developer\Helper\Data::class) + $this->devHelperMock = $this->getMockBuilder(Data::class) ->disableOriginalConstructor() ->getMock(); - $this->debugHintsFactory = $this->getMockBuilder( - \Magento\Developer\Model\TemplateEngine\Decorator\DebugHintsFactory::class + $this->debugHintsFactoryMock = $this->getMockBuilder( + DebugHintsFactory::class ) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); + + $this->httpMock = $this->createMock(Http::class); + + $storeMock = $this->createMock(StoreInterface::class); + $storeMock->expects($this->once()) + ->method('getCode') + ->willReturn(static::STORE_CODE); + $this->storeManagerMock->expects($this->once()) + ->method('getStore') + ->willReturn($storeMock); + + $this->objectManager = new ObjectManager($this); } /** * @param string $debugHintsPath * @param bool $showBlockHints + * @param bool $debugHintsWithParam + * @param bool $debugHintsParameter + * * @return void * @dataProvider afterCreateActiveDataProvider */ @@ -72,40 +115,41 @@ public function testAfterCreateActive( $this->setupConfigFixture($debugHintsPath, true, $showBlockHints); - $engine = $this->createMock(\Magento\Framework\View\TemplateEngineInterface::class); + $engine = $this->createMock(TemplateEngineInterface::class); - $debugHintsDecorator = $this->getMockBuilder( - \Magento\Developer\Model\TemplateEngine\Decorator\DebugHints::class + $debugHintsDecoratorMock = $this->getMockBuilder( + DebugHintsDecorator::class ) ->disableOriginalConstructor() ->getMock(); - $this->debugHintsFactory->expects($this->once()) + $this->debugHintsFactoryMock->expects($this->once()) ->method('create') ->with([ 'subject' => $engine, 'showBlockHints' => $showBlockHints, ]) - ->willReturn($debugHintsDecorator); + ->willReturn($debugHintsDecoratorMock); - $subjectMock = $this->getMockBuilder(\Magento\Framework\View\TemplateEngineFactory::class) + $subjectMock = $this->getMockBuilder(TemplateEngineFactory::class) ->disableOriginalConstructor() ->getMock(); - $this->httpMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - - $debugHints = new DebugHints( - $this->scopeConfigMock, - $this->storeManager, - $this->devHelperMock, - $this->debugHintsFactory, - $debugHintsPath, - $this->httpMock, - $debugHintsWithParam, - $debugHintsParameter + $debugHints = $this->objectManager->getObject( + DebugHints::class, + [ + 'scopeConfig' => $this->scopeConfigMock, + 'storeManager' => $this->storeManagerMock, + 'devHelper' => $this->devHelperMock, + 'debugHintsFactory' => $this->debugHintsFactoryMock, + 'http' => $this->httpMock, + 'debugHintsPath' => $debugHintsPath, + 'debugHintsWithParam' => $debugHintsWithParam, + 'debugHintsParameter' => $debugHintsParameter + ] ); - $this->assertEquals($debugHintsDecorator, $debugHints->afterCreate($subjectMock, $engine)); + $this->assertEquals($debugHintsDecoratorMock, $debugHints->afterCreate($subjectMock, $engine)); } /** @@ -125,6 +169,9 @@ public function afterCreateActiveDataProvider() * @param string $debugHintsPath * @param bool $isDevAllowed * @param bool $showTemplateHints + * @param bool $debugHintsWithParam + * @param bool $debugHintsParameter + * * @return void * @dataProvider afterCreateInactiveDataProvider */ @@ -135,29 +182,30 @@ public function testAfterCreateInactive( $debugHintsWithParam, $debugHintsParameter ) { - $this->devHelperMock->expects($this->any()) + $this->devHelperMock ->method('isDevAllowed') ->willReturn($isDevAllowed); $this->setupConfigFixture($debugHintsPath, $showTemplateHints, true); - $engine = $this->createMock(\Magento\Framework\View\TemplateEngineInterface::class); + $engine = $this->createMock(TemplateEngineInterface::class); - $subjectMock = $this->getMockBuilder(\Magento\Framework\View\TemplateEngineFactory::class) + $subjectMock = $this->getMockBuilder(TemplateEngineFactory::class) ->disableOriginalConstructor() ->getMock(); - $this->httpMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - - $debugHints = new DebugHints( - $this->scopeConfigMock, - $this->storeManager, - $this->devHelperMock, - $this->debugHintsFactory, - $debugHintsPath, - $this->httpMock, - $debugHintsWithParam, - $debugHintsParameter + $debugHints = $this->objectManager->getObject( + DebugHints::class, + [ + 'scopeConfig' => $this->scopeConfigMock, + 'storeManager' => $this->storeManagerMock, + 'devHelper' => $this->devHelperMock, + 'debugHintsFactory' => $this->debugHintsFactoryMock, + 'http' => $this->httpMock, + 'debugHintsPath' => $debugHintsPath, + 'debugHintsWithParam' => $debugHintsWithParam, + 'debugHintsParameter' => $debugHintsParameter + ] ); $this->assertSame($engine, $debugHints->afterCreate($subjectMock, $engine)); @@ -184,32 +232,24 @@ public function afterCreateInactiveDataProvider() * @param string $debugHintsPath * @param bool $showTemplateHints * @param bool $showBlockHints + * * @return void */ - protected function setupConfigFixture($debugHintsPath, $showTemplateHints, $showBlockHints) + private function setupConfigFixture($debugHintsPath, $showTemplateHints, $showBlockHints): void { - $storeCode = 'default'; - $storeMock = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class); - $storeMock->expects($this->once()) - ->method('getCode') - ->willReturn($storeCode); - $this->storeManager->expects($this->once()) - ->method('getStore') - ->willReturn($storeMock); - $this->scopeConfigMock->expects($this->atLeastOnce()) ->method('getValue') ->willReturnMap([ [ $debugHintsPath, ScopeInterface::SCOPE_STORE, - $storeCode, + static::STORE_CODE, $showTemplateHints, ], [ DebugHints::XML_PATH_DEBUG_TEMPLATE_HINTS_BLOCKS, ScopeInterface::SCOPE_STORE, - $storeCode, + static::STORE_CODE, $showBlockHints ] ]); diff --git a/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/PreprocessorStrategyTest.php b/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/PreprocessorStrategyTest.php index 8372092c0e763..4b1b3110b4b9b 100644 --- a/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/PreprocessorStrategyTest.php +++ b/app/code/Magento/Developer/Test/Unit/Model/View/Asset/PreProcessor/PreprocessorStrategyTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Developer\Test\Unit\Model\View\Asset\PreProcessor; use Magento\Developer\Model\Config\Source\WorkflowType; @@ -13,14 +15,14 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Asset\PreProcessor\AlternativeSourceInterface; use Magento\Framework\View\Asset\PreProcessor\Chain; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** - * Class PreprocessorStrategyTest - * * @see \Magento\Developer\Model\View\Asset\PreProcessor\PreprocessorStrategy * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class PreprocessorStrategyTest extends \PHPUnit\Framework\TestCase +class PreprocessorStrategyTest extends TestCase { /** * @var PreprocessorStrategy @@ -28,27 +30,27 @@ class PreprocessorStrategyTest extends \PHPUnit\Framework\TestCase private $preprocessorStrategy; /** - * @var FrontendCompilation|\PHPUnit_Framework_MockObject_MockObject + * @var FrontendCompilation|MockObject */ private $frontendCompilationMock; /** - * @var AlternativeSourceInterface|\PHPUnit_Framework_MockObject_MockObject + * @var AlternativeSourceInterface|MockObject */ private $alternativeSourceMock; /** - * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ private $scopeConfigMock; /** - * @var State|\PHPUnit_Framework_MockObject_MockObject + * @var State|MockObject */ private $stateMock; /** - * @var \Magento\Framework\App\ObjectManager|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\App\ObjectManager|MockObject */ private $objectMangerMock; @@ -71,12 +73,15 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->preprocessorStrategy = (new ObjectManager($this))->getObject(PreprocessorStrategy::class, [ - 'alternativeSource' => $this->alternativeSourceMock, - 'frontendCompilation' => $this->frontendCompilationMock, - 'scopeConfig' => $this->scopeConfigMock, - 'state' => $this->stateMock, - ]); + $this->preprocessorStrategy = (new ObjectManager($this))->getObject( + PreprocessorStrategy::class, + [ + 'alternativeSource' => $this->alternativeSourceMock, + 'frontendCompilation' => $this->frontendCompilationMock, + 'scopeConfig' => $this->scopeConfigMock, + 'state' => $this->stateMock, + ] + ); } /** @@ -148,14 +153,12 @@ public function testProcessAlternativeSource() } /** - * @return Chain|\PHPUnit_Framework_MockObject_MockObject + * @return Chain|MockObject */ private function getChainMock() { - $chainMock = $this->getMockBuilder(Chain::class) + return $this->getMockBuilder(Chain::class) ->disableOriginalConstructor() ->getMock(); - - return $chainMock; } } diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml index 9ae046210181b..317f2abdf2f23 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml @@ -97,8 +97,7 @@ </actionGroup> <!-- Assert product price in cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="openShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="openShoppingCartPage"/> <see selector="{{CheckoutCartProductSection.ProductPriceByName(DownloadableProduct.name)}}" userInput="$51.99" stepKey="assertProductPriceInCart"/> </test> </tests> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml index 30e31be6c8ec4..0ac2dc9b04825 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/EditDownloadableProductWithSeparateLinksFromCartTest.xml @@ -95,8 +95,7 @@ </actionGroup> <!-- Step 4: Open cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="openShoppingCartPage"/> - <waitForPageLoad stepKey="waitForShoppingCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="openShoppingCartPage"/> <see selector="{{CheckoutCartProductSection.ProductPriceByName(DownloadableProduct.name)}}" userInput="$51.99" stepKey="assertProductPriceInCart"/> diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/DownloadablePanel.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/DownloadablePanel.php index a34ef79d70d30..813fcaf863412 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/DownloadablePanel.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/DownloadablePanel.php @@ -45,7 +45,7 @@ public function __construct(LocatorInterface $locator, ArrayManager $arrayManage } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -58,7 +58,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -97,7 +97,8 @@ protected function addMessageBox() 'visible' => false, 'imports' => [ 'visible' => '${$.provider}:' . self::DATA_SCOPE_PRODUCT . '.' - . ProductAttributeInterface::CODE_HAS_WEIGHT + . ProductAttributeInterface::CODE_HAS_WEIGHT, + '__disableTmpl' => ['visible' => false], ], ]; @@ -122,7 +123,8 @@ protected function addCheckboxIsDownloadable() 'sortOrder' => 10, 'imports' => [ 'disabled' => '${$.provider}:' . self::DATA_SCOPE_PRODUCT . '.' - . ProductAttributeInterface::CODE_HAS_WEIGHT + . ProductAttributeInterface::CODE_HAS_WEIGHT, + '__disableTmpl' => ['disabled' => false], ], 'valueMap' => [ 'false' => '0', @@ -130,6 +132,7 @@ protected function addCheckboxIsDownloadable() ], 'samplesFieldset' => 'ns = ${ $.ns }, index=' . Composite::CONTAINER_SAMPLES, 'linksFieldset' => 'ns = ${ $.ns }, index=' . Composite::CONTAINER_LINKS, + '__disableTmpl' => ['samplesFieldset' => false, 'linksFieldset' => false], ]; $this->meta = $this->arrayManager->set($checkboxPath, $this->meta, $checkboxConfig); diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php index 8c98d871a12d2..d4c81763c7d11 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Links.php @@ -287,7 +287,8 @@ protected function getPriceColumn() 'imports' => [ 'linksPurchasedSeparately' => '${$.provider}:data.product' . '.links_purchased_separately', - 'useDefaultPrice' => '${$.parentName}.use_default_price:checked' + 'useDefaultPrice' => '${$.parentName}.use_default_price:checked', + '__disableTmpl' => ['linksPurchasedSeparately' => false, 'useDefaultPrice' => false], ], ]; @@ -485,6 +486,7 @@ protected function getMaxDownloadsColumn() ], 'exports' => [ 'checked' => '${$.parentName}.number_of_downloads:disabled', + '__disableTmpl' => ['checked' => false], ], ]; diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/UsedDefault.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/UsedDefault.php index d0e24ce7c4aca..b00dfef81a705 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/UsedDefault.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/UsedDefault.php @@ -11,6 +11,9 @@ use Magento\Framework\Stdlib\ArrayManager; use Magento\Ui\Component\Form; +/** + * Class for Product Form Modifier User Default + */ class UsedDefault extends AbstractModifier { /** @@ -49,7 +52,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -57,7 +60,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -124,6 +127,7 @@ protected function priceUsedDefault() ], 'imports' => [ 'linksPurchasedSeparately' => '${$.provider}:data.product.links_purchased_separately', + '__disableTmpl' => ['linksPurchasedSeparately' => false], ], ]; $this->meta = $this->arrayManager->set($checkboxPath, $this->meta, $useDefaultConfig); @@ -159,6 +163,7 @@ protected function titleUsedDefaultInGrid($indexTitle) ], 'exports' => [ 'checked' => '${$.parentName}.' . $indexTitle . ':disabled', + '__disableTmpl' => ['checked' => false], ], ]; $this->meta = $this->arrayManager->set($checkboxPath, $this->meta, $useDefaultConfig); diff --git a/app/code/Magento/Elasticsearch/Model/Indexer/Fulltext/Plugin/Category/Product/Action/Rows.php b/app/code/Magento/Elasticsearch/Model/Indexer/Fulltext/Plugin/Category/Product/Action/Rows.php new file mode 100644 index 0000000000000..1d1d23017e68c --- /dev/null +++ b/app/code/Magento/Elasticsearch/Model/Indexer/Fulltext/Plugin/Category/Product/Action/Rows.php @@ -0,0 +1,124 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Elasticsearch\Model\Indexer\Fulltext\Plugin\Category\Product\Action; + +use Magento\Catalog\Model\Indexer\Category\Product\TableMaintainer; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Indexer\IndexerRegistry; +use Magento\CatalogSearch\Model\Indexer\Fulltext as FulltextIndexer; +use Magento\Catalog\Model\Indexer\Category\Product\Action\Rows as ActionRows; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\DB\Adapter\AdapterInterface; + +/** + * Catalog search indexer plugin for catalog category products assignment. + */ +class Rows +{ + /** + * @var IndexerRegistry + */ + private $indexerRegistry; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var AdapterInterface + */ + private $connection; + + /** + * @var TableMaintainer + */ + private $tableMaintainer; + + /** + * @param IndexerRegistry $indexerRegistry + * @param StoreManagerInterface $storeManager + * @param ResourceConnection $resource + * @param TableMaintainer $tableMaintainer + */ + public function __construct( + IndexerRegistry $indexerRegistry, + StoreManagerInterface $storeManager, + ResourceConnection $resource, + TableMaintainer $tableMaintainer + ) { + $this->indexerRegistry = $indexerRegistry; + $this->storeManager = $storeManager; + $this->connection = $resource->getConnection(); + $this->tableMaintainer = $tableMaintainer; + } + + /** + * Reindex after catalog category product reindex. + * + * @param ActionRows $subject + * @param ActionRows $result + * @param array $entityIds + * @param bool $useTempTable + * @return ActionRows + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterExecute( + ActionRows $subject, + ActionRows $result, + array $entityIds, + bool $useTempTable = false + ): ActionRows { + $indexer = $this->indexerRegistry->get(FulltextIndexer::INDEXER_ID); + if (!empty($entityIds) && $indexer->isScheduled()) { + foreach ($this->storeManager->getStores() as $store) { + $indexTable = $this->getIndexTable((int) $store->getId(), $useTempTable); + $productIds = $this->getProductIdsFromIndex($indexTable, $entityIds); + if (!empty($productIds)) { + $indexer->reindexList($productIds); + } + } + } + + return $result; + } + + /** + * Return index table name. + * + * @param int $storeId + * @param bool $useTempTable + * + * @return string + */ + private function getIndexTable(int $storeId, bool $useTempTable) + { + return $useTempTable + ? $this->tableMaintainer->getMainReplicaTable($storeId) + : $this->tableMaintainer->getMainTable($storeId); + } + + /** + * Get all category products from index table. + * + * @param string $indexTable + * @param array $categoryIds + * + * @return array + */ + private function getProductIdsFromIndex(string $indexTable, array $categoryIds): array + { + return $this->connection->fetchCol( + $this->connection->select() + ->from($indexTable, ['product_id']) + ->where('category_id IN (?)', $categoryIds) + ->distinct() + ); + } +} diff --git a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php index ce88fc290e23c..64ce76c729334 100644 --- a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php +++ b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchCriteriaResolver.php @@ -80,6 +80,9 @@ public function resolve(): SearchCriteria $searchCriteria->setRequestName($this->searchRequestName); $searchCriteria->setSortOrders($this->orders); $searchCriteria->setCurrentPage($this->currentPage - 1); + if ($this->size) { + $searchCriteria->setPageSize($this->size); + } return $searchCriteria; } diff --git a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php index 4693b7502c5c1..54b8c1966ee12 100644 --- a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php +++ b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php @@ -69,10 +69,22 @@ public function apply() foreach ($items as $item) { $ids[] = (int)$item->getId(); } - $this->collection->getSelect()->where('e.entity_id IN (?)', $ids); - $orderList = join(',', $ids); - $this->collection->getSelect()->reset(\Magento\Framework\DB\Select::ORDER); - $this->collection->getSelect()->order(new \Zend_Db_Expr("FIELD(e.entity_id,$orderList)")); + $this->collection->getSelect() + ->where('e.entity_id IN (?)', $ids) + ->reset(\Magento\Framework\DB\Select::ORDER); + $sortOrder = $this->searchResult->getSearchCriteria() + ->getSortOrders(); + if (!empty($sortOrder['price']) && $this->collection->getLimitationFilters()->isUsingPriceIndex()) { + $sortDirection = $sortOrder['price']; + $this->collection->getSelect() + ->order( + new \Zend_Db_Expr("price_index.min_price = 0, price_index.min_price {$sortDirection}") + ); + } else { + $orderList = join(',', $ids); + $this->collection->getSelect() + ->order(new \Zend_Db_Expr("FIELD(e.entity_id,$orderList)")); + } } /** diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml index 7983ec3f5ceed..d4ab69129ad68 100644 --- a/app/code/Magento/Elasticsearch/etc/di.xml +++ b/app/code/Magento/Elasticsearch/etc/di.xml @@ -13,6 +13,9 @@ <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\ConverterInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldIndex\Converter" /> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ConverterInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Converter" /> <preference for="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProviderInterface" type="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\CompositeFieldProvider" /> + <type name="Magento\Catalog\Model\Indexer\Category\Product\Action\Rows"> + <plugin name="catalogsearchFulltextProductAssignment" type="Magento\Elasticsearch\Model\Indexer\Fulltext\Plugin\Category\Product\Action\Rows"/> + </type> <type name="Magento\Elasticsearch\Model\Config"> <arguments> <argument name="engineList" xsi:type="array"> diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml index e763df7dd3227..c3b76d4ff1c9e 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6Test.xml @@ -30,38 +30,45 @@ <field key="name">Product Simple AAA</field> </createData> <magentoCLI command="config:set {{CustomGridPerPageValuesConfigData.path}} {{CustomGridPerPageValuesConfigData.value}}" stepKey="setCustomGridPerPageValues"/> + <magentoCLI command="config:set {{CustomGridPerPageDefaultConfigData.path}} {{CustomGridPerPageDefaultConfigData.value}}" stepKey="setCustomGridPerPageDefaults"/> + <magentoCLI stepKey="flushConfigCache" command="cache:flush config"/> + <magentoCron groups="index" stepKey="runCronIndex"/> </before> <after> <deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/> <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> <magentoCLI command="config:set {{DefaultGridPerPageValuesConfigData.path}} {{DefaultGridPerPageValuesConfigData.value}}" stepKey="setDefaultGridPerPageValues"/> + <magentoCLI command="config:set {{DefaultGridPerPageDefaultConfigData.path}} {{DefaultGridPerPageDefaultConfigData.value}}" stepKey="setDefaultGridPerPageDefaults"/> </after> <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="openStorefrontHomePage"/> <actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="quickSearchSimpleProduct"> <argument name="phrase" value="AAA"/> </actionGroup> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertFirstProductOnCatalogSearchPage"> - <argument name="product" value="$createFirstProduct$"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertFirstProductOnCatalogSearchPage"> + <argument name="productName" value="$createFirstProduct.name$"/> </actionGroup> <actionGroup ref="StorefrontCheckProductIsMissingInCategoryProductsPageActionGroup" stepKey="assertSecondProductIsMissingOnCatalogSearchPage"> <argument name="productName" value="$createSecondProduct.name$"/> </actionGroup> <click selector="{{StorefrontCategoryBottomToolbarSection.nextPage}}" stepKey="clickNextPageCatalogSearchPager"/> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertSecondProductOnCatalogSearchPage"> - <argument name="product" value="$createSecondProduct$"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertSecondProductOnCatalogSearchPage"> + <argument name="productName" value="$createSecondProduct.name$"/> </actionGroup> <actionGroup ref="StorefrontCheckProductIsMissingInCategoryProductsPageActionGroup" stepKey="assertFirstProductIsMissingOnCatalogSearchPage"> <argument name="productName" value="$createFirstProduct.name$"/> </actionGroup> <selectOption selector="{{StorefrontCategoryBottomToolbarSection.perPage}}" userInput="2" stepKey="selectDisplayedProductInGridPerPage"/> <waitForPageLoad stepKey="waitForPageLoad"/> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertFirstProductDisplayedOnCatalogSearchPage"> - <argument name="product" value="$createFirstProduct$"/> + + <dontSeeInCurrentUrl stepKey="assertRedirectedToFirstPage" url="?p=2"/> + + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertFirstProductDisplayedOnCatalogSearchPage"> + <argument name="productName" value="$createFirstProduct.name$"/> </actionGroup> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertSecondProductDisplayedOnCatalogSearchPage"> - <argument name="product" value="$createSecondProduct$"/> + <actionGroup ref="AssertStorefrontProductIsPresentOnCategoryPageActionGroup" stepKey="assertSecondProductDisplayedOnCatalogSearchPage"> + <argument name="productName" value="$createSecondProduct.name$"/> </actionGroup> </test> </tests> diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml index b4eb436fc1b2a..1dceb21a7c95c 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontProductQuickSearchUsingElasticSearch6WithNotAvailablePageTest.xml @@ -25,22 +25,11 @@ <remove keyForRemoval="selectDisplayedProductInGridPerPage"/> <remove keyForRemoval="assertFirstProductDisplayedOnCatalogSearchPage"/> <remove keyForRemoval="assertSecondProductDisplayedOnCatalogSearchPage"/> - <grabTextFrom selector="{{StorefrontCategoryBottomToolbarSection.currentPage}}" stepKey="grabNumberOfLastPage"/> - <actionGroup ref="StorefrontQuickSearchWithPaginationActionGroup" stepKey="navigateToUnavailableCatalogSearchResultPage"> + <remove keyForRemoval="selectDisplayedProductInGridPerPage"/> + <remove keyForRemoval="assertStillOnSecondPage"/> + <actionGroup ref="StorefrontQuickSearchWithPaginationActionGroup" stepKey="navigateToUnavailableCatalogSearchResultPage" before="waitForPageLoad"> <argument name="phrase" value="AAA"/> <argument name="pageNumber" value="999"/> </actionGroup> - <scrollTo selector="{{StorefrontCategoryBottomToolbarSection.currentPage}}" stepKey="scrollToBottomToolbarPager"/> - <grabTextFrom selector="{{StorefrontCategoryBottomToolbarSection.currentPage}}" stepKey="grabNumberOfCurrentPage"/> - <assertEquals stepKey="assertCurrentPageIsLastPageOfCatalogSearchResult"> - <expectedResult type="variable">grabNumberOfLastPage</expectedResult> - <actualResult type="variable">grabNumberOfCurrentPage</actualResult> - </assertEquals> - <actionGroup ref="AssertProductOnCategoryPageActionGroup" stepKey="assertProductOnLastCatalogSearchPage"> - <argument name="product" value="$createSecondProduct$"/> - </actionGroup> - <actionGroup ref="StorefrontCheckProductIsMissingInCategoryProductsPageActionGroup" stepKey="assertFirstProductIsMissingOnLastCatalogSearchPage"> - <argument name="productName" value="$createFirstProduct.name$"/> - </actionGroup> </test> </tests> diff --git a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml index 3850bfabc0c34..1c61bd290f005 100644 --- a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml +++ b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml @@ -109,7 +109,7 @@ <actionGroup ref="SearchAdminDataGridByKeywordActionGroup" stepKey="searchOrder"> <argument name="keyword" value="$grabOrderNumber"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <!--Create Invoice--> <actionGroup ref="AdminCreateInvoiceActionGroup" stepKey="createInvoice"/> <!--Create shipping label--> diff --git a/app/code/Magento/GiftMessage/Ui/DataProvider/Product/Modifier/GiftMessage.php b/app/code/Magento/GiftMessage/Ui/DataProvider/Product/Modifier/GiftMessage.php index fe2479d778992..63bf6705854f3 100644 --- a/app/code/Magento/GiftMessage/Ui/DataProvider/Product/Modifier/GiftMessage.php +++ b/app/code/Magento/GiftMessage/Ui/DataProvider/Product/Modifier/GiftMessage.php @@ -161,10 +161,12 @@ protected function customizeAllowGiftMessageField(array $meta) 'exports' => [ 'checked' => '${$.parentName}.' . static::FIELD_MESSAGE_AVAILABLE . ':isUseConfig', + '__disableTmpl' => ['checked' => false], ], 'imports' => [ 'disabled' => '${$.parentName}.' . static::FIELD_MESSAGE_AVAILABLE . ':isUseDefault', + '__disableTmpl' => ['disabled' => false], ] ], ], diff --git a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php index 2ea622c1c2b8f..3ea8c6eb3c2b9 100644 --- a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php +++ b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php @@ -394,9 +394,11 @@ protected function getListing() 'externalFilterMode' => true, 'imports' => [ 'storeId' => '${ $.provider }:data.product.current_store_id', + '__disableTmpl' => ['storeId' => false], ], 'exports' => [ 'storeId' => '${ $.externalProvider }:params.current_store_id', + '__disableTmpl' => ['storeId' => false], ], ], ], @@ -499,7 +501,10 @@ protected function getGrid() 'attribute_set' => 'attribute_set_text', 'thumbnail' => 'thumbnail_src', ], - 'links' => ['insertData' => '${ $.provider }:${ $.dataProvider }'], + 'links' => [ + 'insertData' => '${ $.provider }:${ $.dataProvider }', + '__disableTmpl' => ['insertData' => false], + ], 'sortOrder' => 20, 'columnsHeader' => false, 'columnsHeaderAfterRender' => true, diff --git a/app/code/Magento/Indexer/Test/Mftf/ActionGroup/CliRunReindexUsingCronJobsActionGroup.xml b/app/code/Magento/Indexer/Test/Mftf/ActionGroup/CliRunReindexUsingCronJobsActionGroup.xml deleted file mode 100644 index 50407aff70cd5..0000000000000 --- a/app/code/Magento/Indexer/Test/Mftf/ActionGroup/CliRunReindexUsingCronJobsActionGroup.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="CliRunReindexUsingCronJobsActionGroup" deprecated="Use magentoCron instead"> - <annotations> - <description>Run cron 'index' group which reindex all invalidated indices.</description> - </annotations> - - <magentoCLI command="cron:run" arguments="--group='index'" stepKey="firstRunToScheduleJobs"/> - <magentoCLI command="cron:run" arguments="--group='index'" stepKey="secondRunToExecuteJobs"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Indexer/Test/Mftf/ActionGroup/IndexerActionGroup/AdminReindexAndFlushCacheActionGroup.xml b/app/code/Magento/Indexer/Test/Mftf/ActionGroup/IndexerActionGroup/AdminReindexAndFlushCacheActionGroup.xml deleted file mode 100644 index 42b6b047ae73e..0000000000000 --- a/app/code/Magento/Indexer/Test/Mftf/ActionGroup/IndexerActionGroup/AdminReindexAndFlushCacheActionGroup.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminReindexAndFlushCache"> - <annotations> - <description>Run reindex and flush cache.</description> - </annotations> - - <magentoCLI command="indexer:reindex" stepKey="reindex"/> - <magentoCLI command="cache:flush" stepKey="flushCache"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml index 5f806aca004d4..fc1f92dba7ad6 100644 --- a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml +++ b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityNegativeScenarioTest.xml @@ -55,7 +55,7 @@ <requiredEntity createDataKey="createSimpleProduct"/> </createData> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> <!-- Log in as a customer --> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="customerLoginToStorefront"> <argument name="Customer" value="$customerWithDefaultAddress$"/> @@ -105,7 +105,7 @@ <deleteData createDataKey="createConfigChildProduct1CreateConfigurableProduct" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2CreateConfigurableProduct" stepKey="deleteConfigChildProduct2"/> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndicesAfterTest"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndicesAfterTest"/> </after> <!-- 1. Ensure customer is a guest --> <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="logoutCustomer"/> diff --git a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml index b0235fe32ca27..4283f42660f1f 100644 --- a/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml +++ b/app/code/Magento/InstantPurchase/Test/Mftf/Test/StorefrontInstantPurchaseFunctionalityTest.xml @@ -97,7 +97,7 @@ <deleteData createDataKey="createConfigChildProduct1CreateConfigurableProduct" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2CreateConfigurableProduct" stepKey="deleteConfigChildProduct2"/> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> </after> <!-- 1. Browse all product page and verify that the "Instant Purchase" button appears --> <!-- Virtual product --> diff --git a/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminAllowResourcesAccessIntegrationActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminAllowResourcesAccessIntegrationActionGroup.xml new file mode 100644 index 0000000000000..bf4a9798225cc --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminAllowResourcesAccessIntegrationActionGroup.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminAllowResourcesAccessIntegrationActionGroup"> + <click stepKey="clickAllowButton" selector="{{AdminNewIntegrationSection.allow}}"/> + <waitForPageLoad stepKey="waitForLoading"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminClickEditIntegrationEntityActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminClickEditIntegrationEntityActionGroup.xml new file mode 100644 index 0000000000000..b41ac5a6cc145 --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminClickEditIntegrationEntityActionGroup.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminClickEditIntegrationEntityActionGroup"> + <click stepKey="clickEditButton" selector="{{IntegrationsGridSection.edit}}"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationClickReauthoriseLinkOnGridActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationClickReauthoriseLinkOnGridActionGroup.xml new file mode 100644 index 0000000000000..053dfb11ce319 --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationClickReauthoriseLinkOnGridActionGroup.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminIntegrationClickReauthoriseLinkOnGridActionGroup"> + <click stepKey="clickReauthoriseLink" selector="{{AdminIntegrationsGridSection.activate}}"/> + <waitForPageLoad stepKey="waitForPopupLoading"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/_Deprecated_ActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationOpenExistingEntityActionGroup.xml similarity index 64% rename from app/code/Magento/Catalog/Test/Mftf/ActionGroup/_Deprecated_ActionGroup.xml rename to app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationOpenExistingEntityActionGroup.xml index aff1de23af409..5631da6213bfe 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/_Deprecated_ActionGroup.xml +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationOpenExistingEntityActionGroup.xml @@ -8,5 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="GoToProductPageViaIDActionGroup" extends="AdminProductPageOpenByIdActionGroup" deprecated="Use AdminProductPageOpenByIdActionGroup instead"/> + <actionGroup name="AdminIntegrationOpenExistingEntityActionGroup"> + <click stepKey="clickEditIcon" selector="{{AdminIntegrationsGridSection.edit}}"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationSaveAndActivateActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationSaveAndActivateActionGroup.xml new file mode 100644 index 0000000000000..d5e0cad99181a --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminIntegrationSaveAndActivateActionGroup.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminIntegrationSaveAndActivateActionGroup"> + <click stepKey="clickIntegrationToggle" selector="{{AdminNewIntegrationFormSection.integrationToggle}}"/> + <waitForElementVisible selector="{{AdminNewIntegrationFormSection.saveAndActivate}}" stepKey="waitForSaveAndActivateButton"/> + <click stepKey="clickSaveAndActivateButton" selector="{{AdminNewIntegrationFormSection.saveAndActivate}}"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminSubmitIntegrationFormActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminSubmitIntegrationFormActionGroup.xml new file mode 100644 index 0000000000000..316ff84d8d21c --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminSubmitIntegrationFormActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + <actionGroup name="AdminSubmitIntegrationFormActionGroup"> + <!--Click the "Save" Button --> + <click stepKey="clickSaveButton" selector="{{AddNewIntegrationSection.save}}"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminUpdateCreatedIntegrationEntityActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminUpdateCreatedIntegrationEntityActionGroup.xml new file mode 100644 index 0000000000000..6635deff85e9a --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AdminUpdateCreatedIntegrationEntityActionGroup.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + <!--Fill Required Fields --> + <actionGroup name="AdminUpdateCreatedIntegrationEntityActionGroup"> + <arguments> + <argument name="name" type="string"/> + <argument name="password" type="string"/> + <argument name="endpoint" type="string"/> + <argument name="linkUrl" type="string"/> + </arguments> + <fillField stepKey="fillNameField" selector="{{AddNewIntegrationSection.name}}" userInput="{{name}}"/> + <fillField stepKey="fillEndpiontField" selector="{{AddNewIntegrationSection.endpoint}}" userInput="{{endpoint}}"/> + <fillField stepKey="fillLinkUrlField" selector="{{AddNewIntegrationSection.linkUrl}}" userInput="{{linkUrl}}"/> + <fillField stepKey="fillAdminPasswordField" selector="{{AddNewIntegrationSection.password}}" userInput="{{password}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Integration/Test/Mftf/ActionGroup/AssertUpdatedIntegrationEntityInGridActionGroup.xml b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AssertUpdatedIntegrationEntityInGridActionGroup.xml new file mode 100644 index 0000000000000..c825db4e94728 --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/ActionGroup/AssertUpdatedIntegrationEntityInGridActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertUpdatedIntegrationEntityInGridActionGroup"> + <arguments> + <argument name="name" type="string"/> + </arguments> + <see userInput="{{name}}" selector="{{IntegrationsGridSection.rowByIndex('1')}}" stepKey="seeIntegrationEntity"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationDetailsSection.xml b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationDetailsSection.xml new file mode 100644 index 0000000000000..8b9776f0bd26c --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationDetailsSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminIntegrationDetailsSection"> + <element name="consumerKey" type="input" selector=".admin__field-control.control #integration_properties_consumer_key"/> + <element name="consumerSecret" type="input" selector=".admin__field-control.control #integration_properties_consumer_secret"/> + <element name="accessToken" type="input" selector=".admin__field-control.control #integration_properties_token"/> + <element name="accessTokenSecret" type="input" selector=".admin__field-control.control #integration_properties_token_secret"/> + </section> +</sections> diff --git a/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsGridSection.xml b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsGridSection.xml index ae601542f3b37..7326bef963da1 100644 --- a/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsGridSection.xml +++ b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsGridSection.xml @@ -17,5 +17,6 @@ <element name="submitButton" type="button" selector=".action-primary.action-accept" timeout="30"/> <element name="rowByIndex" type="text" selector="tr[data-role='row']:nth-of-type({{var1}})" parameterized="true" timeout="30"/> <element name="edit" type="button" selector=".data-grid .edit"/> + <element name="activate" type="button" selector="#integrationGrid_table>tbody>tr:nth-child(1)>td.col-activate>a"/> </section> </sections> diff --git a/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsSection/AddNewIntegrationSection.xml b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsSection/AddNewIntegrationSection.xml new file mode 100644 index 0000000000000..2326b924bde8e --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsSection/AddNewIntegrationSection.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AddNewIntegrationSection"> + <element name="name" type="input" selector="#integration_properties_name"/> + <element name="password" type="input" selector="#integration_properties_current_password"/> + <element name="saveButton" type="button" selector=".page-actions #save-split-button-button"/> + <element name="endpoint" type="input" selector="#integration_properties_endpoint"/> + <element name="linkUrl" type="input" selector="#integration_properties_identity_link_url"/> + <element name="save" type="button" selector=".page-actions-buttons .save"/> + </section> +</sections> diff --git a/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsSection/IntegrationsGridSection.xml b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsSection/IntegrationsGridSection.xml new file mode 100644 index 0000000000000..613dec8a9474e --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Section/AdminIntegrationsSection/IntegrationsGridSection.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="IntegrationsGridSection"> + <element name="add" type="button" selector=".page-actions .add"/> + <element name="messageByType" type="block" selector="#messages .message-{{messageType}}" parameterized="true"/> + <element name="name" type="input" selector=".data-grid-filters #integrationGrid_filter_name"/> + <element name="search" type="input" selector=".admin__filter-actions button[title=Search]"/> + <element name="remove" type="button" selector=".data-grid .delete"/> + <element name="submitButton" type="button" selector=".action-primary.action-accept" timeout="30"/> + <element name="rowByIndex" type="text" selector="tr[data-role='row']:nth-of-type({{var1}})" parameterized="true" timeout="30"/> + <element name="edit" type="button" selector=".data-grid .edit"/> + </section> +</sections> diff --git a/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationFormSection.xml b/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationFormSection.xml index edb9e5dd5eb51..8a83f95e7cbba 100644 --- a/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationFormSection.xml +++ b/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationFormSection.xml @@ -18,5 +18,7 @@ <element name="resourceTree" type="block" selector="[data-ui-id='integration-edit-tabs-tab-content-api-section'] [data-role='resource-tree']"/> <element name="save" type="button" selector="#save-split-button-button"/> + <element name="integrationToggle" type="button" selector=".page-actions-buttons .action-toggle.primary"/> + <element name="saveAndActivate" type="button" selector="#save-split-button-activate"/> </section> </sections> diff --git a/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationSection.xml b/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationSection.xml index 3e7214784c2b5..5f2d1a6b8a8eb 100644 --- a/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationSection.xml +++ b/app/code/Magento/Integration/Test/Mftf/Section/AdminNewIntegrationSection.xml @@ -14,5 +14,11 @@ <element name="endpoint" type="input" selector="#integration_properties_endpoint"/> <element name="linkUrl" type="input" selector="#integration_properties_identity_link_url"/> <element name="save" type="button" selector=".page-actions-buttons .save"/> + <element name="allow" type="button" selector=".page-actions-buttons .action-primary"/> + <element name="resourcesPopup" type="block" selector="#modal-content-17 #integration-popup-container"/> + <element name="consumerKey" type="input" selector=".admin__field-control.control #integration_token_consumer_key"/> + <element name="consumerSecret" type="input" selector=".admin__field-control.control #integration_token_consumer_secret"/> + <element name="accessToken" type="input" selector=".admin__field-control.control #integration_token_token"/> + <element name="accessTokenSecret" type="input" selector=".admin__field-control.control #integration_token_token_secret"/> </section> </sections> diff --git a/app/code/Magento/Integration/Test/Mftf/Test/AdminCreateIntegrationEntityWithDuplicatedNameTest.xml b/app/code/Magento/Integration/Test/Mftf/Test/AdminCreateIntegrationEntityWithDuplicatedNameTest.xml index f55e4e37585ba..7bc1c9b5a274f 100644 --- a/app/code/Magento/Integration/Test/Mftf/Test/AdminCreateIntegrationEntityWithDuplicatedNameTest.xml +++ b/app/code/Magento/Integration/Test/Mftf/Test/AdminCreateIntegrationEntityWithDuplicatedNameTest.xml @@ -23,6 +23,14 @@ <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> </before> <after> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="returnToIntegrationsPage"> + <argument name="menuUiId" value="{{AdminMenuSystem.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSystemExtensionsIntegrations.dataUiId}}"/> + </actionGroup> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="searchForIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}}"/> + </actionGroup> + <actionGroup ref="AdminDeleteIntegrationEntityActionGroup" stepKey="deleteCreatedIntegration"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> @@ -32,18 +40,18 @@ </actionGroup> <actionGroup ref="AdminNavigateToCreateIntegrationPageActionGroup" stepKey="clickAddNewIntegrationButton"/> <actionGroup ref="AdminCreatesNewIntegrationActionGroup" stepKey="createNewIntegration"> - <argument name="name" value="Integration1"/> + <argument name="name" value="{{defaultIntegrationData.name}}"/> <argument name="password" value="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> </actionGroup> <actionGroup ref="AdminSubmitNewIntegrationFormActionGroup" stepKey="submitTheForm"/> <actionGroup ref="AdminNavigateToCreateIntegrationPageActionGroup" stepKey="clickAddNewIntegrationButtonSecondTime"/> <actionGroup ref="AdminCreatesNewIntegrationActionGroup" stepKey="createNewIntegrationWithDuplicatedName"> - <argument name="name" value="Integration1"/> + <argument name="name" value="{{defaultIntegrationData.name}}"/> <argument name="password" value="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> </actionGroup> <actionGroup ref="AdminSubmitNewIntegrationFormActionGroup" stepKey="submitTheFormWithDuplicatedName"/> <actionGroup ref="AssertAdminMessageCreateIntegrationEntityActionGroup" stepKey="seeErrorMessage"> - <argument name="message" value="The integration with name "Integration1" exists."/> + <argument name="message" value="The integration with name "{{defaultIntegrationData.name}}" exists."/> <argument value="error" name="messageType"/> </actionGroup> </test> diff --git a/app/code/Magento/Integration/Test/Mftf/Test/AdminDeleteIntegrationEntityTest.xml b/app/code/Magento/Integration/Test/Mftf/Test/AdminDeleteIntegrationEntityTest.xml index eb6c946a03bb5..0148278ac7aaa 100644 --- a/app/code/Magento/Integration/Test/Mftf/Test/AdminDeleteIntegrationEntityTest.xml +++ b/app/code/Magento/Integration/Test/Mftf/Test/AdminDeleteIntegrationEntityTest.xml @@ -31,34 +31,32 @@ <actionGroup ref="AdminNavigateToCreateIntegrationPageActionGroup" stepKey="clickAddNewIntegrationButton"/> <!-- Create New Integration --> <actionGroup ref="AdminCreatesNewIntegrationActionGroup" stepKey="createIntegration"> - <argument name="name" value="Integration1"/> + <argument name="name" value="{{defaultIntegrationData.name}}"/> <argument name="password" value="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> </actionGroup> - <!-- Submit The Form --> <actionGroup ref="AdminSubmitNewIntegrationFormActionGroup" stepKey="submitTheForm"/> </before> <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> - <!-- TEST BODY --> <!-- Find Created Integration In Grid --> <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="findCreatedIntegration"> - <argument name="name" value="Integration1"/> + <argument name="name" value="{{defaultIntegrationData.name}}"/> </actionGroup> <!-- Delete Created Integration Entity --> <actionGroup ref="AdminDeleteIntegrationEntityActionGroup" stepKey="deleteIntegration"/> <!-- Assert Success Message --> <actionGroup ref="AssertAdminMessageCreateIntegrationEntityActionGroup" stepKey="seeSuccessMessage"> - <argument name="message" value="The integration 'Integration1' has been deleted."/> + <argument name="message" value="The integration '{{defaultIntegrationData.name}}' has been deleted."/> <argument value="success" name="messageType"/> </actionGroup> <!-- Assert Deleted Integration Is Not In Grid --> <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="findDeletedIntegration"> - <argument name="name" value="Integration1"/> + <argument name="name" value="{{defaultIntegrationData.name}}"/> </actionGroup> <actionGroup ref="AssertDeletedIntegrationIsNotInGridActionGroup" stepKey="dontSeeIntegration"> - <argument name="name" value="Integration1"/> + <argument name="name" value="{{defaultIntegrationData.name}}"/> </actionGroup> <!-- END TEST BODY --> </test> diff --git a/app/code/Magento/Integration/Test/Mftf/Test/AdminReAuthorizeTokensIntegrationEntityTest.xml b/app/code/Magento/Integration/Test/Mftf/Test/AdminReAuthorizeTokensIntegrationEntityTest.xml new file mode 100644 index 0000000000000..480cc4b8861d3 --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Test/AdminReAuthorizeTokensIntegrationEntityTest.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminReAuthorizeTokensIntegrationEntityTest"> + <annotations> + <features value="Integration"/> + <stories value="System Integration"/> + <title value="Reauthorise Integration's Tokens"/> + <description value="ReAuthorising Tokens For Created Integration"/> + <group value="integration"/> + <group value="mtf_migrated"/> + <testCaseId value="MC-14397"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToIntegrationsPage"> + <argument name="menuUiId" value="{{AdminMenuSystem.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSystemExtensionsIntegrations.dataUiId}}"/> + </actionGroup> + <actionGroup ref="AdminNavigateToCreateIntegrationPageActionGroup" stepKey="clickAddNewIntegrationButton"/> + <actionGroup ref="AdminFillIntegrationFormActionGroup" stepKey="createIntegration"> + <argument name="integration" value="defaultIntegrationData"/> + <argument name="password" value="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> + </actionGroup> + <actionGroup ref="AdminIntegrationSaveAndActivateActionGroup" stepKey="clickSaveAndActivateButton"/> + <actionGroup ref="AdminAllowResourcesAccessIntegrationActionGroup" stepKey="allowAccess"/> + </before> + <after> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="returnToIntegrationsPage"> + <argument name="menuUiId" value="{{AdminMenuSystem.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSystemExtensionsIntegrations.dataUiId}}"/> + </actionGroup> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="searchForReAuthorizedIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}}"/> + </actionGroup> + <actionGroup ref="AdminDeleteIntegrationEntityActionGroup" stepKey="deleteCreatedIntegration"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + + <grabValueFrom selector="{{AdminNewIntegrationSection.consumerKey}}" stepKey="grabConsumerKey"/> + <grabValueFrom selector="{{AdminNewIntegrationSection.consumerSecret}}" stepKey="grabConsumerSecret"/> + <grabValueFrom selector="{{AdminNewIntegrationSection.accessToken}}" stepKey="grabAccessToken"/> + <grabValueFrom selector="{{AdminNewIntegrationSection.accessTokenSecret}}" stepKey="grabAccessTokenSecret"/> + <actionGroup ref="AdminAllowResourcesAccessIntegrationActionGroup" stepKey="clickDoneButton"/> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="findCreatedIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}}"/> + </actionGroup> + <actionGroup ref="AdminIntegrationClickReauthoriseLinkOnGridActionGroup" stepKey="clickReauthoriseLink"/> + <actionGroup ref="AdminAllowResourcesAccessIntegrationActionGroup" stepKey="clickReauthoriseButton"/> + <grabValueFrom selector="{{AdminNewIntegrationSection.consumerKey}}" stepKey="grabAfterReauthorizeConsumerKey"/> + <grabValueFrom selector="{{AdminNewIntegrationSection.consumerSecret}}" stepKey="grabAfterReauthorizeConsumerSecret"/> + <grabValueFrom selector="{{AdminNewIntegrationSection.accessToken}}" stepKey="grabReauthorizedAccessToken"/> + <grabValueFrom selector="{{AdminNewIntegrationSection.accessTokenSecret}}" stepKey="grabReauthorizedAccessTokenSecret"/> + <actionGroup ref="AdminAllowResourcesAccessIntegrationActionGroup" stepKey="finishTheProcess"/> + <actionGroup ref="AssertMessageInAdminPanelActionGroup" stepKey="seeSuccessMessage"> + <argument name="message" value="The integration '{{defaultIntegrationData.name}}' has been re-authorized."/> + </actionGroup> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="findReAuthorizedIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}}"/> + </actionGroup> + <actionGroup ref="AdminIntegrationOpenExistingEntityActionGroup" stepKey="openIntegrationEntity"/> + <assertEquals stepKey="assertConsumerKey"> + <actualResult type="string">$grabAfterReauthorizeConsumerKey</actualResult> + <expectedResult type="const">($grabConsumerKey)</expectedResult> + </assertEquals> + <assertEquals stepKey="assertConsumerSecret"> + <actualResult type="string">$grabAfterReauthorizeConsumerSecret</actualResult> + <expectedResult type="const">($grabConsumerSecret)</expectedResult> + </assertEquals> + <assertNotEquals stepKey="assertNotEqualsToken"> + <actualResult type="string">$grabReauthorizedAccessToken</actualResult> + <expectedResult type="const">($grabAccessToken)</expectedResult> + </assertNotEquals> + <assertNotEquals stepKey="assertNotEqualsTokenSecret"> + <actualResult type="string">$grabReauthorizedAccessTokenSecret</actualResult> + <expectedResult type="const">($grabAccessTokenSecret)</expectedResult> + </assertNotEquals> + </test> +</tests> diff --git a/app/code/Magento/Integration/Test/Mftf/Test/AdminUpdateIntegrationEntityTest.xml b/app/code/Magento/Integration/Test/Mftf/Test/AdminUpdateIntegrationEntityTest.xml new file mode 100644 index 0000000000000..50aa83bc79eed --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Test/AdminUpdateIntegrationEntityTest.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminUpdateIntegrationEntityTest"> + <annotations> + <features value="Integration"/> + <stories value="System Integration"/> + <title value="Updating System Integration Entity"/> + <description value="Admin Updates Created Integration"/> + <group value="integration"/> + <testCaseId value="MC-14398"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <!-- Login As Admin --> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + <!-- Navigate To Integrations Page --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToIntegrationsPage"> + <argument name="menuUiId" value="{{AdminMenuSystem.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSystemExtensionsIntegrations.dataUiId}}"/> + </actionGroup> + <!-- Click the "Add New Integration" button --> + <actionGroup ref="AdminNavigateToCreateIntegrationPageActionGroup" stepKey="clickAddNewIntegrationButton"/> + <!-- Create New Integration --> + <actionGroup ref="AdminCreatesNewIntegrationActionGroup" stepKey="createIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}}"/> + <argument name="password" value="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> + </actionGroup> + <actionGroup ref="AdminSubmitNewIntegrationFormActionGroup" stepKey="submitTheForm"/> + </before> + <after> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="returnToIntegrationsPage"> + <argument name="menuUiId" value="{{AdminMenuSystem.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSystemExtensionsIntegrations.dataUiId}}"/> + </actionGroup> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="searchForIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}} Updated"/> + </actionGroup> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + </after> + + <!-- TEST BODY --> + <!-- Find Created Integration In Grid --> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="findCreatedIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}}"/> + </actionGroup> + <!-- Open Integration Edit Page --> + <actionGroup ref="AdminClickEditIntegrationEntityActionGroup" stepKey="clickEditButton"/> + <!-- Update Integration Entity --> + <actionGroup ref="AdminUpdateCreatedIntegrationEntityActionGroup" stepKey="updateIntegrationEntity"> + <argument name="name" value="{{defaultIntegrationData.name}} Updated"/> + <argument name="endpoint" value="https://endpoint-updated.com"/> + <argument name="linkUrl" value="https://testlink-updated.com"/> + <argument name="password" value="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> + </actionGroup> + <!-- Submit The Form --> + <actionGroup ref="AdminSubmitIntegrationFormActionGroup" stepKey="submitTheForm"/> + <!-- Assert Success Message --> + <actionGroup ref="AssertAdminMessageCreateIntegrationEntityActionGroup" stepKey="seeSuccessMessage"> + <argument name="message" value="The integration '{{defaultIntegrationData.name}} Updated' has been saved."/> + <argument value="success" name="messageType"/> + </actionGroup> + <!-- Assert Updated Entity In Grid --> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="findDeletedIntegration"> + <argument name="name" value="{{defaultIntegrationData.name}} Updated"/> + </actionGroup> + <actionGroup ref="AssertUpdatedIntegrationEntityInGridActionGroup" stepKey="seeIntegrationEntity"> + <argument name="name" value="{{defaultIntegrationData.name}} Updated"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Integration/Test/Mftf/Test/AdminUpdateIntegrationEntityWithIncorrectPasswordTest.xml b/app/code/Magento/Integration/Test/Mftf/Test/AdminUpdateIntegrationEntityWithIncorrectPasswordTest.xml new file mode 100644 index 0000000000000..4be4301146a04 --- /dev/null +++ b/app/code/Magento/Integration/Test/Mftf/Test/AdminUpdateIntegrationEntityWithIncorrectPasswordTest.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminUpdateIntegrationEntityWithIncorrectPasswordTest"> + <annotations> + <features value="Integration"/> + <stories value="System Integration"/> + <title value="Updating System Integration Entity with Incorrect Password"/> + <description value="Admin Updates Created Integration with Incorrect Password"/> + <group value="integration"/> + <testCaseId value="MC-14399"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <!-- Login As Admin --> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + <!-- Navigate To Integrations Page --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToIntegrationsPage"> + <argument name="menuUiId" value="{{AdminMenuSystem.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSystemExtensionsIntegrations.dataUiId}}"/> + </actionGroup> + <!-- Click the "Add New Integration" button --> + <actionGroup ref="AdminNavigateToCreateIntegrationPageActionGroup" stepKey="clickAddNewIntegrationButton"/> + <!-- Create New Integration --> + <actionGroup ref="AdminCreatesNewIntegrationActionGroup" stepKey="createIntegration"> + <argument name="name" value="Integration1"/> + <argument name="password" value="{{_ENV.MAGENTO_ADMIN_PASSWORD}}"/> + </actionGroup> + <actionGroup ref="AdminSubmitNewIntegrationFormActionGroup" stepKey="submitTheForm"/> + </before> + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + </after> + + <!-- TEST BODY --> + <!-- Find Created Integration In Grid --> + <actionGroup ref="AdminSearchIntegrationInGridActionGroup" stepKey="findCreatedIntegration"> + <argument name="name" value="Integration1"/> + </actionGroup> + <!-- Open Integration Edit Page --> + <actionGroup ref="AdminClickEditIntegrationEntityActionGroup" stepKey="clickEditButton"/> + <!-- Update Integration Entity --> + <actionGroup ref="AdminUpdateCreatedIntegrationEntityActionGroup" stepKey="updateIntegrationEntity"> + <argument name="name" value="Integration Updated"/> + <argument name="endpoint" value="https://endpoint-updated.com"/> + <argument name="linkUrl" value="https://testlink-updated.com"/> + <argument name="password" value="12345test"/> + </actionGroup> + <!-- Submit The Form --> + <actionGroup ref="AdminSubmitIntegrationFormActionGroup" stepKey="submitTheForm"/> + <!-- Assert Error Message --> + <actionGroup ref="AssertAdminMessageCreateIntegrationEntityActionGroup" stepKey="seeErrorMessage"> + <argument name="message" value="The password entered for the current user is invalid. Verify the password and try again."/> + <argument value="error" name="messageType"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Authorizenet/LICENSE.txt b/app/code/Magento/MediaContent/LICENSE.txt similarity index 100% rename from app/code/Magento/Authorizenet/LICENSE.txt rename to app/code/Magento/MediaContent/LICENSE.txt diff --git a/app/code/Magento/Authorizenet/LICENSE_AFL.txt b/app/code/Magento/MediaContent/LICENSE_AFL.txt similarity index 100% rename from app/code/Magento/Authorizenet/LICENSE_AFL.txt rename to app/code/Magento/MediaContent/LICENSE_AFL.txt diff --git a/app/code/Magento/MediaContent/Model/Content/Config/Converter.php b/app/code/Magento/MediaContent/Model/Content/Config/Converter.php new file mode 100644 index 0000000000000..854d10c8d9812 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/Content/Config/Converter.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model\Content\Config; + +use Magento\Framework\Config\ConverterInterface; + +/** + * Media Content configuration Converter + */ +class Converter implements ConverterInterface +{ + /* + * Search tag name + */ + private const SEARCH_TAG_NAME = 'search'; + + /** + * Patterns tag name + */ + private const PATTERNS_TAG_NAME = 'patterns'; + + /** + * Pattern tag name + */ + private const PATTERN_TAG_NAME = 'pattern'; + + /** + * Convert dom node to array + * + * @param \DOMDocument $source + * @return array + */ + public function convert($source) : array + { + $result = []; + + if (!$source instanceof \DOMDocument) { + throw new \InvalidArgumentException('The source should be instance of DOMDocument'); + } + + foreach ($source->getElementsByTagName(self::SEARCH_TAG_NAME) as $search) { + $result[self::SEARCH_TAG_NAME] = []; + foreach ($search->getElementsByTagName(self::PATTERNS_TAG_NAME) as $patterns) { + $result[self::SEARCH_TAG_NAME][self::PATTERNS_TAG_NAME] = []; + foreach ($patterns->getElementsByTagName(self::PATTERN_TAG_NAME) as $pattern) { + $result[self::SEARCH_TAG_NAME][self::PATTERNS_TAG_NAME] + [$pattern->attributes->getNamedItem('name')->nodeValue] = $pattern->nodeValue; + } + } + } + + return $result; + } +} diff --git a/app/code/Magento/MediaContent/Model/Content/Config/SchemaLocator.php b/app/code/Magento/MediaContent/Model/Content/Config/SchemaLocator.php new file mode 100644 index 0000000000000..76a13b213ce8e --- /dev/null +++ b/app/code/Magento/MediaContent/Model/Content/Config/SchemaLocator.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model\Content\Config; + +use Magento\Framework\Config\SchemaLocatorInterface; +use Magento\Framework\Module\Dir; +use Magento\Framework\Module\Dir\Reader; + +/** + * Media Content configuration schema locator + */ +class SchemaLocator implements SchemaLocatorInterface +{ + /** + * Path to corresponding XSD file with validation rules for both individual and merged configs + * + * @var string + */ + private $schema; + + /** + * @param Reader $moduleReader + */ + public function __construct(Reader $moduleReader) + { + $this->schema = $moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Magento_MediaContentApi') + . '/media_content.xsd'; + } + + /** + * Get path to merged config schema + * + * @return string|null + */ + public function getSchema() + { + return $this->schema; + } + + /** + * Get path to per file validation schema + * + * @return string|null + */ + public function getPerFileSchema() + { + return $this->schema; + } +} diff --git a/app/code/Magento/MediaContent/Model/Content/SearchPatternConfig.php b/app/code/Magento/MediaContent/Model/Content/SearchPatternConfig.php new file mode 100644 index 0000000000000..32c667a3d6069 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/Content/SearchPatternConfig.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model\Content; + +use Magento\Framework\Config\DataInterface; +use Magento\MediaContentApi\Model\SearchPatternConfigInterface; + +/** + * Media content configuration + */ +class SearchPatternConfig implements SearchPatternConfigInterface +{ + private const XML_PATH_SEARCH_PATTERNS = 'search/patterns'; + + /** + * @var DataInterface + */ + private $data; + + /** + * @param DataInterface $data + */ + public function __construct(DataInterface $data) + { + $this->data = $data; + } + + /** + * Retrieve search RegExp patterns for finding media asset paths within content + * + * @return array + */ + public function get(): array + { + return $this->data->get(self::XML_PATH_SEARCH_PATTERNS); + } +} diff --git a/app/code/Magento/MediaContent/Model/ContentAssetLink.php b/app/code/Magento/MediaContent/Model/ContentAssetLink.php new file mode 100644 index 0000000000000..abfafd39c4a23 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/ContentAssetLink.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface; +use Magento\MediaContentApi\Api\Data\ContentAssetLinkExtensionInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; + +/** + * Relation of the media asset to the media content + */ +class ContentAssetLink implements ContentAssetLinkInterface +{ + /** + * @var ContentAssetLinkExtensionInterface|null + */ + private $extensionAttributes; + + /** + * @var ContentIdentityInterface + */ + private $contentIdentity; + + /** + * @var int + */ + private $assetId; + + /** + * ContentAssetLink constructor. + * @param int $assetId + * @param ContentIdentityInterface $contentIdentity + * @param ContentAssetLinkExtensionInterface|null $extensionAttributes + */ + public function __construct( + int $assetId, + ContentIdentityInterface $contentIdentity, + ?ContentAssetLinkExtensionInterface $extensionAttributes = null + ) { + $this->assetId = $assetId; + $this->contentIdentity = $contentIdentity; + $this->extensionAttributes = $extensionAttributes; + } + + /** + * @inheritdoc + */ + public function getAssetId(): int + { + return $this->assetId; + } + + /** + * @inheritdoc + */ + public function getContentId(): ContentIdentityInterface + { + return $this->contentIdentity; + } + + /** + * @inheritdoc + */ + public function getExtensionAttributes(): ?ContentAssetLinkExtensionInterface + { + return $this->extensionAttributes; + } + + /** + * @inheritdoc + */ + public function setExtensionAttributes(?ContentAssetLinkExtensionInterface $extensionAttributes): void + { + $this->extensionAttributes = $extensionAttributes; + } +} diff --git a/app/code/Magento/MediaContent/Model/ContentIdentity.php b/app/code/Magento/MediaContent/Model/ContentIdentity.php new file mode 100644 index 0000000000000..fd60aa8f19430 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/ContentIdentity.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityExtensionInterface; + +/** + * @inheritdoc + */ +class ContentIdentity implements ContentIdentityInterface +{ + private $entityType; + private $entityId; + private $field; + private $extensionAttributes; + + /** + * ContentIdentity constructor. + * @param string $entityType + * @param string $entityId + * @param string $field + * @param ContentIdentityExtensionInterface|null $extensionAttributes + */ + public function __construct( + string $entityType, + string $entityId, + string $field, + ?ContentIdentityExtensionInterface $extensionAttributes = null + ) { + $this->entityType = $entityType; + $this->entityId= $entityId; + $this->field = $field; + $this->extensionAttributes = $extensionAttributes; + } + + /** + * @inheritdoc + */ + public function getEntityType(): string + { + return $this->entityType; + } + + /** + * @inheritdoc + */ + public function getEntityId(): string + { + return $this->entityId; + } + + /** + * @inheritdoc + */ + public function getField(): string + { + return $this->field; + } + + /** + * @inheritdoc + */ + public function getExtensionAttributes(): ?ContentIdentityExtensionInterface + { + return $this->extensionAttributes; + } + + /** + * @inheritdoc + */ + public function setExtensionAttributes(?ContentIdentityExtensionInterface $extensionAttributes): void + { + $this->extensionAttributes = $extensionAttributes; + } +} diff --git a/app/code/Magento/MediaContent/Model/DeleteContentAssetLinks.php b/app/code/Magento/MediaContent/Model/DeleteContentAssetLinks.php new file mode 100644 index 0000000000000..543347c872e73 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/DeleteContentAssetLinks.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\CouldNotDeleteException; +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface; +use Magento\MediaContentApi\Api\DeleteContentAssetLinksInterface; +use Psr\Log\LoggerInterface; + +/** + * Used to delete links of the media asset to the media content + */ +class DeleteContentAssetLinks implements DeleteContentAssetLinksInterface +{ + private const MEDIA_CONTENT_ASSET_TABLE_NAME = 'media_content_asset'; + private const ASSET_ID = 'asset_id'; + private const ENTITY_TYPE = 'entity_type'; + private const ENTITY_ID = 'entity_id'; + private const FIELD = 'field'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct(ResourceConnection $resourceConnection, LoggerInterface $logger) + { + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * Remove relation between the media asset and the content. I.e media asset no longer part of the content + * + * @param ContentAssetLinkInterface[] $contentAssetLinks + * @throws CouldNotDeleteException + */ + public function execute(array $contentAssetLinks): void + { + try { + $connection = $this->resourceConnection->getConnection(); + $tableName = $this->resourceConnection->getTableName(self::MEDIA_CONTENT_ASSET_TABLE_NAME); + $whereSql = $this->buildWhereSqlPart($contentAssetLinks); + $connection->delete($tableName, $whereSql); + } catch (\Exception $exception) { + $this->logger->critical($exception); + throw new CouldNotDeleteException( + __('An error occurred at deleting links between the media asset and media content.') + ); + } + } + + /** + * Build sql where condition + * + * @param ContentAssetLinkInterface[] $contentAssetLinks + * @return string + */ + private function buildWhereSqlPart(array $contentAssetLinks): string + { + $connection = $this->resourceConnection->getConnection(); + $condition = []; + foreach ($contentAssetLinks as $contentAssetLink) { + $assetId = $connection->quoteInto(self::ASSET_ID . ' = ?', $contentAssetLink->getAssetId()); + $entityId = $connection->quoteInto( + self::ENTITY_ID . ' = ?', + $contentAssetLink->getContentId()->getEntityId() + ); + $entityType = $connection->quoteInto( + self::ENTITY_TYPE . ' = ?', + $contentAssetLink->getContentId()->getEntityType() + ); + $field = $connection->quoteInto( + self::FIELD . ' = ?', + $contentAssetLink->getContentId()->getField() + ); + $condition[] = '(' . $assetId . ' AND ' . $entityId . ' AND ' . $entityType . ' AND ' . $field . ')'; + } + return implode(' OR ', $condition); + } +} diff --git a/app/code/Magento/MediaContent/Model/DeleteContentAssetLinksByAssetIds.php b/app/code/Magento/MediaContent/Model/DeleteContentAssetLinksByAssetIds.php new file mode 100644 index 0000000000000..68495adb468d7 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/DeleteContentAssetLinksByAssetIds.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\MediaContentApi\Api\DeleteContentAssetLinksByAssetIdsInterface; +use Magento\Framework\Exception\CouldNotDeleteException; +use Psr\Log\LoggerInterface; + +/** + * Delete the relation between media asset and the piece of content. I.e media asset no longer part of the content + */ +class DeleteContentAssetLinksByAssetIds implements DeleteContentAssetLinksByAssetIdsInterface +{ + private const MEDIA_CONTENT_ASSET_TABLE_NAME = 'media_content_asset'; + private const ASSET_ID = 'asset_id'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct(ResourceConnection $resourceConnection, LoggerInterface $logger) + { + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * Delete media content relations by media asset ids + * + * @param array $assetIds + * @throws CouldNotDeleteException + */ + public function execute(array $assetIds): void + { + $commaSeparatedAssetIds = implode(', ', $assetIds); + try { + $this->resourceConnection->getConnection()->delete( + $this->resourceConnection->getTableName(self::MEDIA_CONTENT_ASSET_TABLE_NAME), + [ + self::ASSET_ID . ' IN (?)' => $commaSeparatedAssetIds + ] + ); + } catch (\Exception $exception) { + $this->logger->critical($exception); + $message = __( + 'Could not remove media content relations for assets ids: %ids', + [ + 'ids' => $commaSeparatedAssetIds + ] + ); + throw new CouldNotDeleteException($message, $exception); + } + } +} diff --git a/app/code/Magento/MediaContent/Model/ExtractAssetsFromContent.php b/app/code/Magento/MediaContent/Model/ExtractAssetsFromContent.php new file mode 100644 index 0000000000000..92248ee1debfe --- /dev/null +++ b/app/code/Magento/MediaContent/Model/ExtractAssetsFromContent.php @@ -0,0 +1,112 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\MediaContentApi\Model\SearchPatternConfigInterface; +use Magento\MediaContentApi\Api\ExtractAssetsFromContentInterface; +use Magento\MediaGalleryApi\Api\Data\AssetInterface; +use Magento\MediaGalleryApi\Model\Asset\Command\GetByPathInterface; +use Psr\Log\LoggerInterface; + +/** + * Used for extracting media asset list from a media content by the search pattern. + */ +class ExtractAssetsFromContent implements ExtractAssetsFromContentInterface +{ + /** + * @var SearchPatternConfigInterface + */ + private $searchPatternConfig; + + /** + * @var GetByPathInterface + */ + private $getMediaAssetByPath; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param SearchPatternConfigInterface $searchPatternConfig + * @param GetByPathInterface $getMediaAssetByPath + * @param LoggerInterface $logger + */ + public function __construct( + SearchPatternConfigInterface $searchPatternConfig, + GetByPathInterface $getMediaAssetByPath, + LoggerInterface $logger + ) { + $this->searchPatternConfig = $searchPatternConfig; + $this->getMediaAssetByPath = $getMediaAssetByPath; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(string $content): array + { + $matchesArrays = []; + + foreach ($this->searchPatternConfig->get() as $pattern) { + if (empty($pattern)) { + continue; + } + + preg_match_all($pattern, $content, $matches, PREG_PATTERN_ORDER); + + if (!empty($matches[1])) { + $matchesArrays[] = $matches[1]; + } + } + + return $this->getAssetsByPaths(array_unique(array_merge([], ...$matchesArrays))); + } + + /** + * Get media assets by paths array + * + * @param array $paths + * @return AssetInterface[] + */ + private function getAssetsByPaths(array $paths): array + { + $assets = []; + + foreach ($paths as $path) { + $path = htmlspecialchars_decode($path); + $path = trim($path, '"\''); + try { + /** @var AssetInterface $asset */ + $asset = $this->getMediaAssetByPath->execute($this->getPathStartingWithSlash($path)); + $assets[$asset->getId()] = $asset; + } catch (\Exception $exception) { + $this->logger->critical($exception); + } + } + + return $assets; + } + + /** + * Ensure the extracted paths matches the standard format + * + * @param string $path + * @return string + */ + private function getPathStartingWithSlash(string $path): string + { + $normalizedPath = ltrim($path, '/'); + if (strpos($normalizedPath, '/') !== false) { + return $normalizedPath; + } + return '/' . $normalizedPath; + } +} diff --git a/app/code/Magento/MediaContent/Model/GetAssetIdsByContentIdentity.php b/app/code/Magento/MediaContent/Model/GetAssetIdsByContentIdentity.php new file mode 100644 index 0000000000000..55f357d4ff1b2 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/GetAssetIdsByContentIdentity.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\IntegrationException; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; +use Magento\MediaContentApi\Api\GetAssetIdsByContentIdentityInterface; +use Psr\Log\LoggerInterface; + +/** + * Used to return media asset id list which is used in the specified media content + */ +class GetAssetIdsByContentIdentity implements GetAssetIdsByContentIdentityInterface +{ + private const MEDIA_CONTENT_ASSET_TABLE_NAME = 'media_content_asset'; + private const ASSET_ID = 'asset_id'; + private const ENTITY_TYPE = 'entity_type'; + private const ENTITY_ID = 'entity_id'; + private const FIELD = 'field'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * GetAssetsUsedInContent constructor. + * + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct(ResourceConnection $resourceConnection, LoggerInterface $logger) + { + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(ContentIdentityInterface $contentIdentity): array + { + try { + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->from( + $this->resourceConnection->getTableName(self::MEDIA_CONTENT_ASSET_TABLE_NAME), + self::ASSET_ID + )->where( + self::ENTITY_TYPE . ' = ?', + $contentIdentity->getEntityType() + )->where( + self::ENTITY_ID . '= ?', + $contentIdentity->getEntityId() + )->where( + self::FIELD . '= ?', + $contentIdentity->getField() + ); + + return array_keys($connection->fetchAssoc($select)); + } catch (\Exception $exception) { + $this->logger->critical($exception); + $message = __('An error occurred at getting asset used in content information.'); + throw new IntegrationException($message); + } + } +} diff --git a/app/code/Magento/MediaContent/Model/GetContentByAssetIds.php b/app/code/Magento/MediaContent/Model/GetContentByAssetIds.php new file mode 100644 index 0000000000000..e5a428b7ccae5 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/GetContentByAssetIds.php @@ -0,0 +1,84 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\IntegrationException; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterfaceFactory; +use Magento\MediaContentApi\Api\GetContentByAssetIdsInterface; +use Psr\Log\LoggerInterface; + +/** + * Used to return media asset list for the specified asset. + */ +class GetContentByAssetIds implements GetContentByAssetIdsInterface +{ + private const MEDIA_CONTENT_ASSET_TABLE_NAME = 'media_content_asset'; + private const ASSET_ID = 'asset_id'; + private const ENTITY_TYPE = 'entity_type'; + private const ENTITY_ID = 'entity_id'; + private const FIELD = 'field'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var ContentIdentityInterfaceFactory + */ + private $factory; + + /** + * @param ContentIdentityInterfaceFactory $factory + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct( + ContentIdentityInterfaceFactory $factory, + ResourceConnection $resourceConnection, + LoggerInterface $logger + ) { + $this->factory = $factory; + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(array $assetIds): array + { + try { + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->distinct() + ->from( + $this->resourceConnection->getTableName(self::MEDIA_CONTENT_ASSET_TABLE_NAME), + ['entityType' => self::ENTITY_TYPE, 'entityId' => self::ENTITY_ID, self::FIELD] + ) + ->where(self::ASSET_ID . ' IN (?)', $assetIds); + + $contentIdentities = []; + foreach ($connection->fetchAssoc($select) as $contentIdentityData) { + $contentIdentities[] = $this->factory->create($contentIdentityData); + } + return $contentIdentities; + } catch (\Exception $exception) { + $this->logger->critical($exception); + throw new IntegrationException( + __('An error occurred at getting media asset to content relation by media asset id.') + ); + } + } +} diff --git a/app/code/Magento/MediaContent/Model/SaveContentAssetLinks.php b/app/code/Magento/MediaContent/Model/SaveContentAssetLinks.php new file mode 100644 index 0000000000000..3d4ed2c0e4b80 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/SaveContentAssetLinks.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\MediaContentApi\Api\SaveContentAssetLinksInterface; +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface; +use Psr\Log\LoggerInterface; + +/** + * Used for saving relation between the media asset and media content where the media asset is used + */ +class SaveContentAssetLinks implements SaveContentAssetLinksInterface +{ + private const MEDIA_CONTENT_ASSET_TABLE_NAME = 'media_content_asset'; + private const ASSET_ID = 'asset_id'; + private const ENTITY_TYPE = 'entity_type'; + private const ENTITY_ID = 'entity_id'; + private const FIELD = 'field'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct(ResourceConnection $resourceConnection, LoggerInterface $logger) + { + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * Save a media asset to content link. + * + * @param ContentAssetLinkInterface[] $contentAssetLinks + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function execute(array $contentAssetLinks): void + { + try { + $connection = $this->resourceConnection->getConnection(); + $tableName = $this->resourceConnection->getTableName(self::MEDIA_CONTENT_ASSET_TABLE_NAME); + $data = []; + foreach ($contentAssetLinks as $contentAssetLink) { + $data[] = [ + self::ASSET_ID => $contentAssetLink->getAssetId(), + self::ENTITY_TYPE => $contentAssetLink->getContentId()->getEntityType(), + self::ENTITY_ID => $contentAssetLink->getContentId()->getEntityId(), + self::FIELD => $contentAssetLink->getContentId()->getField() + ]; + } + $connection->insertMultiple($tableName, $data); + } catch (\Exception $exception) { + $this->logger->critical($exception); + throw new CouldNotSaveException( + __('An error occurred while saving relation between media asset and media content.'), + $exception + ); + } + } +} diff --git a/app/code/Magento/MediaContent/Model/UpdateContentAssetLinks.php b/app/code/Magento/MediaContent/Model/UpdateContentAssetLinks.php new file mode 100644 index 0000000000000..d71978d3ca092 --- /dev/null +++ b/app/code/Magento/MediaContent/Model/UpdateContentAssetLinks.php @@ -0,0 +1,131 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\Framework\Exception\CouldNotDeleteException; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Framework\Exception\IntegrationException; +use Magento\MediaContentApi\Api\SaveContentAssetLinksInterface; +use Magento\MediaContentApi\Api\DeleteContentAssetLinksInterface; +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterfaceFactory; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; +use Magento\MediaContentApi\Api\ExtractAssetsFromContentInterface; +use Magento\MediaContentApi\Api\GetAssetIdsByContentIdentityInterface; +use Magento\MediaContentApi\Api\UpdateContentAssetLinksInterface; +use Magento\MediaGalleryApi\Api\Data\AssetInterface; +use Psr\Log\LoggerInterface; + +/** + * Process relation managing between media asset and content: create or delete link if exists. + */ +class UpdateContentAssetLinks implements UpdateContentAssetLinksInterface +{ + private const ASSET_ID = 'assetId'; + private const CONTENT_IDENTITY = 'contentIdentity'; + + /** + * @var ExtractAssetsFromContentInterface + */ + private $extractAssetFromContent; + + /** + * @var SaveContentAssetLinksInterface + */ + private $saveContentAssetLinks; + + /** + * @var DeleteContentAssetLinksInterface + */ + private $deleteContentAssetLinks; + + /** + * @var ContentAssetLinkInterfaceFactory + */ + private $contentAssetLinkFactory; + + /** + * @var GetAssetIdsByContentIdentityInterface + */ + private $getAssetIdsByContentIdentity; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param ExtractAssetsFromContentInterface $extractAssetFromContent + * @param SaveContentAssetLinksInterface $saveContentAssetLinks + * @param DeleteContentAssetLinksInterface $deleteContentAssetLinks + * @param ContentAssetLinkInterfaceFactory $contentAssetLinkFactory + * @param GetAssetIdsByContentIdentityInterface $getAssetIdsByContentIdentity + * @param LoggerInterface $logger + */ + public function __construct( + ExtractAssetsFromContentInterface $extractAssetFromContent, + SaveContentAssetLinksInterface $saveContentAssetLinks, + DeleteContentAssetLinksInterface $deleteContentAssetLinks, + ContentAssetLinkInterfaceFactory $contentAssetLinkFactory, + GetAssetIdsByContentIdentityInterface $getAssetIdsByContentIdentity, + LoggerInterface $logger + ) { + $this->extractAssetFromContent = $extractAssetFromContent; + $this->saveContentAssetLinks = $saveContentAssetLinks; + $this->deleteContentAssetLinks = $deleteContentAssetLinks; + $this->contentAssetLinkFactory = $contentAssetLinkFactory; + $this->getAssetIdsByContentIdentity = $getAssetIdsByContentIdentity; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(ContentIdentityInterface $contentIdentity, string $data): void + { + try { + $this->updateRelation($contentIdentity, $data); + } catch (\Exception $exception) { + $this->logger->critical($exception); + } + } + + /** + * Find out which relations are obsolete and which are new and update them + * + * @param ContentIdentityInterface $contentIdentity + * @param string $data + * @throws CouldNotDeleteException + * @throws CouldNotSaveException + * @throws IntegrationException + */ + private function updateRelation(ContentIdentityInterface $contentIdentity, string $data) + { + $existingAssetIds = $this->getAssetIdsByContentIdentity->execute($contentIdentity); + $currentAssets = $this->extractAssetFromContent->execute($data); + /** @var AssetInterface $asset */ + foreach ($currentAssets as $asset) { + if (!in_array($asset->getId(), $existingAssetIds)) { + $contentAssetLink = $this->contentAssetLinkFactory->create([ + self::ASSET_ID => $asset->getId(), + self::CONTENT_IDENTITY => $contentIdentity + ]); + $this->saveContentAssetLinks->execute([$contentAssetLink]); + } + } + + foreach ($existingAssetIds as $assetId) { + if (!isset($currentAssets[$assetId])) { + $contentAssetLink = $this->contentAssetLinkFactory->create([ + self::ASSET_ID => $assetId, + self::CONTENT_IDENTITY => $contentIdentity + ]); + $this->deleteContentAssetLinks->execute([$contentAssetLink]); + } + } + } +} diff --git a/app/code/Magento/MediaContent/Plugin/MediaGalleryAssetDeleteByDirectoryPath.php b/app/code/Magento/MediaContent/Plugin/MediaGalleryAssetDeleteByDirectoryPath.php new file mode 100644 index 0000000000000..c260c877cdb4a --- /dev/null +++ b/app/code/Magento/MediaContent/Plugin/MediaGalleryAssetDeleteByDirectoryPath.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Plugin; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Exception\CouldNotDeleteException; +use Magento\MediaContentApi\Api\DeleteContentAssetLinksByAssetIdsInterface; +use Magento\MediaGalleryApi\Api\DeleteDirectoriesByPathsInterface; +use Psr\Log\LoggerInterface; + +/** + * Remove media content record after media gallery asset removal. + */ +class MediaGalleryAssetDeleteByDirectoryPath +{ + private const TABLE_MEDIA_GALLERY_ASSET = 'media_gallery_asset'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var DeleteContentAssetLinksByAssetIdsInterface + */ + private $deleteContentAssetLinksByAssetIds; + + /** + * @param DeleteContentAssetLinksByAssetIdsInterface $deleteContentAssetLinksByAssetIds + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct( + DeleteContentAssetLinksByAssetIdsInterface $deleteContentAssetLinksByAssetIds, + ResourceConnection $resourceConnection, + LoggerInterface $logger + ) { + $this->deleteContentAssetLinksByAssetIds = $deleteContentAssetLinksByAssetIds; + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * Around plugin on execute method + * + * @param DeleteDirectoriesByPathsInterface $subject + * @param \Closure $proceed + * @param array $paths + * @throws CouldNotDeleteException + * @return void + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function aroundExecute( + DeleteDirectoriesByPathsInterface $subject, + \Closure $proceed, + array $paths + ) : void { + $assetIdsArrays =[]; + foreach ($paths as $path) { + $assetIdsArrays[] = $this->getAssetIdsByDirectoryPath($path); + } + + $assetIds = array_unique(array_merge([], ...$assetIdsArrays)); + + $proceed($paths); + + $this->deleteContentAssetLinksByAssetIds->execute($assetIds); + } + + /** + * Get ids of media assets by directory path + * + * @param string $path + * @return int[] + */ + private function getAssetIdsByDirectoryPath(string $path): array + { + /** @var AdapterInterface $connection */ + $connection = $this->resourceConnection->getConnection(); + $galleryAssetTableName = $this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET); + + $select = $connection->select(); + $select->from($galleryAssetTableName, ['id']); + $select->where('path LIKE ?', $path . '%'); + return $connection->fetchCol($select); + } +} diff --git a/app/code/Magento/MediaContent/Plugin/MediaGalleryAssetDeleteByPath.php b/app/code/Magento/MediaContent/Plugin/MediaGalleryAssetDeleteByPath.php new file mode 100644 index 0000000000000..83df5c13f36c8 --- /dev/null +++ b/app/code/Magento/MediaContent/Plugin/MediaGalleryAssetDeleteByPath.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Plugin; + +use Magento\Framework\Exception\CouldNotDeleteException; +use Magento\Framework\Exception\LocalizedException; +use Magento\MediaContentApi\Api\DeleteContentAssetLinksByAssetIdsInterface; +use Magento\MediaGalleryApi\Api\Data\AssetInterface; +use Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface; +use Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface; +use Psr\Log\LoggerInterface; + +/** + * Remove media content record after media gallery asset removal. + */ +class MediaGalleryAssetDeleteByPath +{ + /** + * @var GetAssetsByPathsInterface + */ + private $getByPaths; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var DeleteContentAssetLinksByAssetIdsInterface + */ + private $deleteContentAssetLinksByAssetIds; + + /** + * @param DeleteContentAssetLinksByAssetIdsInterface $deleteContentAssetLinksByAssetIds + * @param GetAssetsByPathsInterface $getByPath + * @param LoggerInterface $logger + */ + public function __construct( + DeleteContentAssetLinksByAssetIdsInterface $deleteContentAssetLinksByAssetIds, + GetAssetsByPathsInterface $getByPath, + LoggerInterface $logger + ) { + $this->deleteContentAssetLinksByAssetIds = $deleteContentAssetLinksByAssetIds; + $this->getByPaths = $getByPath; + $this->logger = $logger; + } + + /** + * Around plugin on execute method + * + * @param DeleteAssetsByPathsInterface $subject + * @param \Closure $proceed + * @param array $paths + * @throws CouldNotDeleteException + * @throws LocalizedException + * @return void + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function aroundExecute( + DeleteAssetsByPathsInterface $subject, + \Closure $proceed, + array $paths + ) : void { + $assets = $this->getByPaths->execute($paths); + + $proceed($paths); + + $assetIds = array_map( + function (AssetInterface $asset) { + return $asset->getId(); + }, + $assets + ); + + $this->deleteContentAssetLinksByAssetIds->execute($assetIds); + } +} diff --git a/app/code/Magento/MediaContent/README.md b/app/code/Magento/MediaContent/README.md new file mode 100644 index 0000000000000..b5813540acef7 --- /dev/null +++ b/app/code/Magento/MediaContent/README.md @@ -0,0 +1,13 @@ +# Magento_MediaContent module + +The Magento_MediaContent module provides implementations for managing relations between content and media files used in that content. + +## Extensibility + +Extension developers can interact with the Magento_MediaContent module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). + +[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_MediaContent module. + +## Additional information + +For information about significant changes in patch releases, see [2.3.x Release information](https://devdocs.magento.com/guides/v2.3/release-notes/bk-release-notes.html). diff --git a/app/code/Magento/MediaContent/composer.json b/app/code/Magento/MediaContent/composer.json new file mode 100644 index 0000000000000..6734c1a300810 --- /dev/null +++ b/app/code/Magento/MediaContent/composer.json @@ -0,0 +1,23 @@ +{ + "name": "magento/module-media-content", + "description": "Magento module provides the implementation for managing relations between content and media files used in that content", + "require": { + "php": "~7.1.3||~7.2.0||~7.3.0", + "magento/framework": "*", + "magento/module-media-content-api": "*", + "magento/module-media-gallery-api": "*" + }, + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\MediaContent\\": "" + } + } +} diff --git a/app/code/Magento/MediaContent/etc/db_schema.xml b/app/code/Magento/MediaContent/etc/db_schema.xml new file mode 100644 index 0000000000000..7e45e29cbb434 --- /dev/null +++ b/app/code/Magento/MediaContent/etc/db_schema.xml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="media_content_asset" resource="default" engine="innodb" comment="Relation between media content and media asset"> + <column xsi:type="int" padding="10" name="asset_id" unsigned="true" nullable="false" comment="Entity ID"/> + <column xsi:type="varchar" length="255" name="entity_type" nullable="false" comment="Content type"/> + <column xsi:type="varchar" length="255" name="entity_id" nullable="false" comment="Content entity id"/> + <column xsi:type="varchar" length="255" name="field" nullable="false" comment="Content field"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="entity_type"/> + <column name="entity_id"/> + <column name="field"/> + <column name="asset_id"/> + </constraint> + <index referenceId="MEDIA_CONTENT_ASSET_ASSET_ID" indexType="btree"> + <column name="asset_id"/> + </index> + </table> +</schema> diff --git a/app/code/Magento/MediaContent/etc/db_schema_whitelist.json b/app/code/Magento/MediaContent/etc/db_schema_whitelist.json new file mode 100644 index 0000000000000..e33768b5e1ab5 --- /dev/null +++ b/app/code/Magento/MediaContent/etc/db_schema_whitelist.json @@ -0,0 +1,16 @@ +{ + "media_content_asset": { + "column": { + "entity_type": true, + "entity_id": true, + "field": true, + "asset_id": true + }, + "index": { + "MEDIA_CONTENT_ASSET_ASSET_ID": true + }, + "constraint": { + "PRIMARY": true + } + } +} diff --git a/app/code/Magento/MediaContent/etc/di.xml b/app/code/Magento/MediaContent/etc/di.xml new file mode 100644 index 0000000000000..35dcf2aa836a0 --- /dev/null +++ b/app/code/Magento/MediaContent/etc/di.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <preference for="Magento\MediaContentApi\Api\DeleteContentAssetLinksByAssetIdsInterface" type="Magento\MediaContent\Model\DeleteContentAssetLinksByAssetIds"/> + <preference for="Magento\MediaContentApi\Api\GetAssetIdsByContentIdentityInterface" type="Magento\MediaContent\Model\GetAssetIdsByContentIdentity"/> + <preference for="Magento\MediaContentApi\Api\GetContentByAssetIdsInterface" type="Magento\MediaContent\Model\GetContentByAssetIds"/> + <preference for="Magento\MediaContentApi\Api\ExtractAssetsFromContentInterface" type="Magento\MediaContent\Model\ExtractAssetsFromContent"/> + <preference for="Magento\MediaContentApi\Api\UpdateContentAssetLinksInterface" type="Magento\MediaContent\Model\UpdateContentAssetLinks"/> + <preference for="Magento\MediaContentApi\Api\DeleteContentAssetLinksInterface" type="Magento\MediaContent\Model\DeleteContentAssetLinks"/> + <preference for="Magento\MediaContentApi\Api\SaveContentAssetLinksInterface" type="Magento\MediaContent\Model\SaveContentAssetLinks"/> + <preference for="Magento\MediaContentApi\Api\Data\ContentIdentityInterface" type="Magento\MediaContent\Model\ContentIdentity"/> + <preference for="Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface" type="Magento\MediaContent\Model\ContentAssetLink"/> + <preference for="Magento\MediaContentApi\Model\SearchPatternConfigInterface" type="Magento\MediaContent\Model\Content\SearchPatternConfig"/> + <preference for="Magento\MediaContent\Model\Content\ConfigInterface" type="Magento\MediaContent\Model\Content\Config"/> + <type name="Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface"> + <plugin name="remove_media_content_after_asset_is_removed_by_path" type="Magento\MediaContent\Plugin\MediaGalleryAssetDeleteByPath" /> + </type> + <type name="Magento\MediaGalleryApi\Api\DeleteDirectoriesByPathsInterface"> + <plugin name="remove_media_content_after_asset_is_removed_by_directory_path" type="Magento\MediaContent\Plugin\MediaGalleryAssetDeleteByDirectoryPath" /> + </type> + <virtualType name="Magento\MediaContent\Model\Content\Config\Reader" type="Magento\Framework\Config\Reader\Filesystem"> + <arguments> + <argument name="fileName" xsi:type="string">media_content.xml</argument> + <argument name="converter" xsi:type="object">Magento\MediaContent\Model\Content\Config\Converter</argument> + <argument name="schemaLocator" xsi:type="object">Magento\MediaContent\Model\Content\Config\SchemaLocator</argument> + <argument name="idAttributes" xsi:type="array"> + <item name="/config/search/patterns/pattern" xsi:type="string">name</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\MediaContent\Model\Content\Config\Data" type="Magento\Framework\Config\Data"> + <arguments> + <argument name="reader" xsi:type="object">Magento\MediaContent\Model\Content\Config\Reader</argument> + <argument name="cacheId" xsi:type="string">Media_Content_Patterns_CacheId</argument> + </arguments> + </virtualType> + <type name="Magento\MediaContent\Model\Content\SearchPatternConfig"> + <arguments> + <argument name="data" xsi:type="object">Magento\MediaContent\Model\Content\Config\Data</argument> + </arguments> + </type> +</config> diff --git a/app/code/Magento/AuthorizenetGraphQl/etc/module.xml b/app/code/Magento/MediaContent/etc/module.xml similarity index 85% rename from app/code/Magento/AuthorizenetGraphQl/etc/module.xml rename to app/code/Magento/MediaContent/etc/module.xml index 85a780a881975..58cff2aabf3a6 100644 --- a/app/code/Magento/AuthorizenetGraphQl/etc/module.xml +++ b/app/code/Magento/MediaContent/etc/module.xml @@ -6,5 +6,5 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_AuthorizenetGraphQl"/> + <module name="Magento_MediaContent"/> </config> diff --git a/app/code/Magento/AuthorizenetGraphQl/registration.php b/app/code/Magento/MediaContent/registration.php similarity index 87% rename from app/code/Magento/AuthorizenetGraphQl/registration.php rename to app/code/Magento/MediaContent/registration.php index 2e50f9fe92aaa..d6776f29f46df 100644 --- a/app/code/Magento/AuthorizenetGraphQl/registration.php +++ b/app/code/Magento/MediaContent/registration.php @@ -7,4 +7,4 @@ use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_AuthorizenetGraphQl', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_MediaContent', __DIR__); diff --git a/app/code/Magento/MediaContentApi/Api/Data/ContentAssetLinkInterface.php b/app/code/Magento/MediaContentApi/Api/Data/ContentAssetLinkInterface.php new file mode 100644 index 0000000000000..5ff490655d464 --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/Data/ContentAssetLinkInterface.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api\Data; + +use Magento\Framework\Api\ExtensibleDataInterface; +use Magento\MediaContentApi\Api\Data\ContentAssetLinkExtensionInterface; + +/** + * Data interface representing the identificator of content. I.e. short description field of product entity with id 42 + * @api + */ +interface ContentAssetLinkInterface extends ExtensibleDataInterface +{ + /** + * Return the object that represent content identity + * + * @return ContentIdentityInterface + */ + public function getContentId(): ContentIdentityInterface; + + /** + * Array of assets related to the content entity + * + * @return int + */ + public function getAssetId(): int; + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\MediaContentApi\Api\Data\ContentAssetLinkExtensionInterface|null + */ + public function getExtensionAttributes(): ?ContentAssetLinkExtensionInterface; + + /** + * Set extension attributes + * + * @param \Magento\MediaContentApi\Api\Data\ContentAssetLinkExtensionInterface|null $extensionAttributes + * @return void + */ + public function setExtensionAttributes(?ContentAssetLinkExtensionInterface $extensionAttributes): void; +} diff --git a/app/code/Magento/MediaContentApi/Api/Data/ContentIdentityInterface.php b/app/code/Magento/MediaContentApi/Api/Data/ContentIdentityInterface.php new file mode 100644 index 0000000000000..f1b701fe9d964 --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/Data/ContentIdentityInterface.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api\Data; + +use Magento\Framework\Api\ExtensibleDataInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityExtensionInterface; + +/** + * Data interface representing the identificator of content. I.e. short description field of product entity with id 42 + * @api + */ +interface ContentIdentityInterface extends ExtensibleDataInterface +{ + /** + * Type of entity that can have a content with media. I.e. catalog_product or cms_page + * + * @return string + */ + public function getEntityType(): string; + + /** + * Id of the entity containing content with media + * + * @return string + */ + public function getEntityId(): string; + + /** + * Field of the entity where the content can be stored. I.e. short_description for product + * + * @return string + */ + public function getField(): string; + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\MediaContentApi\Api\Data\ContentIdentityExtensionInterface|null + */ + public function getExtensionAttributes(): ?ContentIdentityExtensionInterface; + + /** + * Set extension attributes + * + * @param \Magento\MediaContentApi\Api\Data\ContentIdentityExtensionInterface|null $extensionAttributes + * @return void + */ + public function setExtensionAttributes(?ContentIdentityExtensionInterface $extensionAttributes): void; +} diff --git a/app/code/Magento/MediaContentApi/Api/DeleteContentAssetLinksByAssetIdsInterface.php b/app/code/Magento/MediaContentApi/Api/DeleteContentAssetLinksByAssetIdsInterface.php new file mode 100644 index 0000000000000..8997e4b6e7e77 --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/DeleteContentAssetLinksByAssetIdsInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api; + +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface; + +/** + * Delete the relation between media asset and the piece of content. I.e media asset no longer part of the content + * @api + */ +interface DeleteContentAssetLinksByAssetIdsInterface +{ + /** + * Delete relation between the media asset and the content. I.e media asset no longer part of the content + * + * @param int[] $assetIds + * @throws \Magento\Framework\Exception\CouldNotDeleteException + */ + public function execute(array $assetIds): void; +} diff --git a/app/code/Magento/MediaContentApi/Api/DeleteContentAssetLinksInterface.php b/app/code/Magento/MediaContentApi/Api/DeleteContentAssetLinksInterface.php new file mode 100644 index 0000000000000..9c50793f51303 --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/DeleteContentAssetLinksInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api; + +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface; + +/** + * Remove the relation between media asset and the piece of content. I.e media asset no longer part of the content + * @api + */ +interface DeleteContentAssetLinksInterface +{ + /** + * Remove relation between the media asset and the content. I.e media asset no longer part of the content + * + * @param ContentAssetLinkInterface[] $contentAssetLinks + * @throws \Magento\Framework\Exception\CouldNotDeleteException + */ + public function execute(array $contentAssetLinks): void; +} diff --git a/app/code/Magento/MediaContentApi/Api/ExtractAssetsFromContentInterface.php b/app/code/Magento/MediaContentApi/Api/ExtractAssetsFromContentInterface.php new file mode 100644 index 0000000000000..4f95571f30ffd --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/ExtractAssetsFromContentInterface.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api; + +use Magento\MediaGalleryApi\Api\Data\AssetInterface; + +/** + * Parse the content string for references to media assets and return the list of identified media assets + * @api + */ +interface ExtractAssetsFromContentInterface +{ + /** + * Parse the content string for references to media assets and return the list of identified media assets + * + * @param string $content + * @return AssetInterface[] + */ + public function execute(string $content): array; +} diff --git a/app/code/Magento/MediaContentApi/Api/GetAssetIdsByContentIdentityInterface.php b/app/code/Magento/MediaContentApi/Api/GetAssetIdsByContentIdentityInterface.php new file mode 100644 index 0000000000000..4316a0d6ee33d --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/GetAssetIdsByContentIdentityInterface.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api; + +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; + +/** + * Get media asset ids that are used in the piece of content identified by the specified content identity + * @api + */ +interface GetAssetIdsByContentIdentityInterface +{ + /** + * Get media asset ids that are used in the piece of content identified by the specified content identity + * + * @param ContentIdentityInterface $contentIdentity + * @return int[] + * @throws \Magento\Framework\Exception\IntegrationException + */ + public function execute(ContentIdentityInterface $contentIdentity): array; +} diff --git a/app/code/Magento/MediaContentApi/Api/GetContentByAssetIdsInterface.php b/app/code/Magento/MediaContentApi/Api/GetContentByAssetIdsInterface.php new file mode 100644 index 0000000000000..cb117545c257e --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/GetContentByAssetIdsInterface.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api; + +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; + +/** + * Get list of content identifiers for pieces of content that include the specified media asset + * @api + */ +interface GetContentByAssetIdsInterface +{ + /** + * Get list of content identifiers for pieces of content that include the specified media asset + * + * @param int[] $assetIds + * @return ContentIdentityInterface[] + * @throws \Magento\Framework\Exception\IntegrationException + */ + public function execute(array $assetIds): array; +} diff --git a/app/code/Magento/MediaContentApi/Api/SaveContentAssetLinksInterface.php b/app/code/Magento/MediaContentApi/Api/SaveContentAssetLinksInterface.php new file mode 100644 index 0000000000000..1c86953ce6f84 --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/SaveContentAssetLinksInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api; + +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface; + +/** + * Save a media asset to content relation. + * @api + */ +interface SaveContentAssetLinksInterface +{ + /** + * Save a media asset to content relation. Should be executed when media assets is added to the content + * + * @param ContentAssetLinkInterface[] $contentAssetLinks + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function execute(array $contentAssetLinks): void; +} diff --git a/app/code/Magento/MediaContentApi/Api/UpdateContentAssetLinksInterface.php b/app/code/Magento/MediaContentApi/Api/UpdateContentAssetLinksInterface.php new file mode 100644 index 0000000000000..c552e8bb2149b --- /dev/null +++ b/app/code/Magento/MediaContentApi/Api/UpdateContentAssetLinksInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContentApi\Api; + +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; + +/** + * Update the media assets to content relations. Assign new media assets and unassign media assets no longer used + */ +interface UpdateContentAssetLinksInterface +{ + /** + * Update the media assets to content relations. Assign new media assets and unassign media assets no longer used + * + * @param ContentIdentityInterface $contentIdentity + * @param string $content + */ + public function execute(ContentIdentityInterface $contentIdentity, string $content): void; +} diff --git a/app/code/Magento/Authorizenet/Test/Mftf/LICENSE.txt b/app/code/Magento/MediaContentApi/LICENSE.txt similarity index 100% rename from app/code/Magento/Authorizenet/Test/Mftf/LICENSE.txt rename to app/code/Magento/MediaContentApi/LICENSE.txt diff --git a/app/code/Magento/Authorizenet/Test/Mftf/LICENSE_AFL.txt b/app/code/Magento/MediaContentApi/LICENSE_AFL.txt similarity index 100% rename from app/code/Magento/Authorizenet/Test/Mftf/LICENSE_AFL.txt rename to app/code/Magento/MediaContentApi/LICENSE_AFL.txt diff --git a/app/code/Magento/MediaContentApi/Model/SearchPatternConfigInterface.php b/app/code/Magento/MediaContentApi/Model/SearchPatternConfigInterface.php new file mode 100644 index 0000000000000..c6715615ffe39 --- /dev/null +++ b/app/code/Magento/MediaContentApi/Model/SearchPatternConfigInterface.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\MediaContentApi\Model; + +/** + * Interface for Media content Config. + */ +interface SearchPatternConfigInterface +{ + /** + * Retrieve search RegExp patterns for finding media asset paths within content + * + * @return array + */ + public function get(): array; +} diff --git a/app/code/Magento/MediaContentApi/README.md b/app/code/Magento/MediaContentApi/README.md new file mode 100644 index 0000000000000..87e0d7524f59b --- /dev/null +++ b/app/code/Magento/MediaContentApi/README.md @@ -0,0 +1,13 @@ +# Magento_MediaContentApi module + +The Magento_MediaContentApi module provides interfaces for managing relations between content and media files used in that content. + +## Extensibility + +Extension developers can interact with the Magento_MediaContent module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). + +[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_MediaContent module. + +## Additional information + +For information about significant changes in patch releases, see [2.3.x Release information](https://devdocs.magento.com/guides/v2.3/release-notes/bk-release-notes.html). diff --git a/app/code/Magento/MediaContentApi/composer.json b/app/code/Magento/MediaContentApi/composer.json new file mode 100644 index 0000000000000..f8c27093280f6 --- /dev/null +++ b/app/code/Magento/MediaContentApi/composer.json @@ -0,0 +1,22 @@ +{ + "name": "magento/module-media-content-api", + "description": "Magento module provides the API interfaces for managing relations between content and media files used in that content", + "require": { + "php": "~7.1.3||~7.2.0||~7.3.0", + "magento/module-media-gallery-api": "*", + "magento/framework": "*" + }, + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\MediaContentApi\\": "" + } + } +} diff --git a/app/code/Magento/MediaContentApi/etc/media_content.xsd b/app/code/Magento/MediaContentApi/etc/media_content.xsd new file mode 100644 index 0000000000000..bcc7eb1105072 --- /dev/null +++ b/app/code/Magento/MediaContentApi/etc/media_content.xsd @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="config" type="configType"> + </xs:element> + + <xs:complexType name="configType"> + <xs:sequence> + <xs:element type="searchType" name="search" maxOccurs="unbounded" minOccurs="1"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="searchType"> + <xs:annotation> + <xs:documentation> + Search used for find assets in content + </xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element type="patternsType" name="patterns" maxOccurs="unbounded" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="patternsType"> + <xs:annotation> + <xs:documentation> + List of RegExp patterns that used for find assets + </xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element type="patternType" name="pattern" maxOccurs="unbounded" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="patternType"> + <xs:simpleContent> + <xs:annotation> + <xs:documentation> + RegExp pattern that used for find assets + </xs:documentation> + </xs:annotation> + <xs:extension base="xs:string"> + <xs:attribute type="xs:string" name="name" use="required"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> +</xs:schema> diff --git a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/etc/module.xml b/app/code/Magento/MediaContentApi/etc/module.xml similarity index 79% rename from dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/etc/module.xml rename to app/code/Magento/MediaContentApi/etc/module.xml index 378b61946ef3a..3aa553170fe2a 100644 --- a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/etc/module.xml +++ b/app/code/Magento/MediaContentApi/etc/module.xml @@ -6,5 +6,5 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_TestModuleAuthorizenetAcceptjs" /> -</config> \ No newline at end of file + <module name="Magento_MediaContentApi" /> +</config> diff --git a/app/code/Magento/AuthorizenetAcceptjs/registration.php b/app/code/Magento/MediaContentApi/registration.php similarity index 87% rename from app/code/Magento/AuthorizenetAcceptjs/registration.php rename to app/code/Magento/MediaContentApi/registration.php index 52a0c497a0993..fb3faefa2734f 100644 --- a/app/code/Magento/AuthorizenetAcceptjs/registration.php +++ b/app/code/Magento/MediaContentApi/registration.php @@ -3,9 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_AuthorizenetAcceptjs', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_MediaContentApi', __DIR__); diff --git a/app/code/Magento/AuthorizenetAcceptjs/LICENSE.txt b/app/code/Magento/MediaContentCatalog/LICENSE.txt similarity index 100% rename from app/code/Magento/AuthorizenetAcceptjs/LICENSE.txt rename to app/code/Magento/MediaContentCatalog/LICENSE.txt diff --git a/app/code/Magento/AuthorizenetAcceptjs/LICENSE_AFL.txt b/app/code/Magento/MediaContentCatalog/LICENSE_AFL.txt similarity index 100% rename from app/code/Magento/AuthorizenetAcceptjs/LICENSE_AFL.txt rename to app/code/Magento/MediaContentCatalog/LICENSE_AFL.txt diff --git a/app/code/Magento/MediaContentCatalog/Observer/Category.php b/app/code/Magento/MediaContentCatalog/Observer/Category.php new file mode 100644 index 0000000000000..21767e0199ae6 --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/Observer/Category.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContentCatalog\Observer; + +use Magento\Catalog\Model\Category as CatalogCategory; +use Magento\Framework\Event\Observer; +use Magento\Framework\Event\ObserverInterface; +use Magento\MediaContentApi\Api\UpdateContentAssetLinksInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterfaceFactory; + +/** + * Observe the catalog_category_save_after event and run processing relation between category content and media asset. + */ +class Category implements ObserverInterface +{ + private const CONTENT_TYPE = 'catalog_category'; + private const TYPE = 'entityType'; + private const ENTITY_ID = 'entityId'; + private const FIELD = 'field'; + + /** + * @var UpdateContentAssetLinksInterface + */ + private $updateContentAssetLinks; + + /** + * @var array + */ + private $fields; + + /** + * @var ContentIdentityInterfaceFactory + */ + private $contentIdentityFactory; + + /** + * @param ContentIdentityInterfaceFactory $contentIdentityFactory + * @param UpdateContentAssetLinksInterface $updateContentAssetLinks + * @param array $fields + */ + public function __construct( + ContentIdentityInterfaceFactory $contentIdentityFactory, + UpdateContentAssetLinksInterface $updateContentAssetLinks, + array $fields + ) { + $this->contentIdentityFactory = $contentIdentityFactory; + $this->updateContentAssetLinks = $updateContentAssetLinks; + $this->fields = $fields; + } + + /** + * Retrieve the saved category and pass it to the model processor to save content - asset relations + * + * @param Observer $observer + */ + public function execute(Observer $observer): void + { + $model = $observer->getEvent()->getData('category'); + + if ($model instanceof CatalogCategory) { + foreach ($this->fields as $field) { + if (!$model->dataHasChangedFor($field)) { + continue; + } + $this->updateContentAssetLinks->execute( + $this->contentIdentityFactory->create( + [ + self::TYPE => self::CONTENT_TYPE, + self::FIELD => $field, + self::ENTITY_ID => (string) $model->getId(), + ] + ), + (string) $model->getData($field) + ); + } + } + } +} diff --git a/app/code/Magento/MediaContentCatalog/Observer/Product.php b/app/code/Magento/MediaContentCatalog/Observer/Product.php new file mode 100644 index 0000000000000..e69cc8486f62f --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/Observer/Product.php @@ -0,0 +1,84 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContentCatalog\Observer; + +use Magento\Catalog\Model\Product as CatalogProduct; +use Magento\Framework\Event\Observer; +use Magento\Framework\Event\ObserverInterface; +use Magento\MediaContentApi\Api\UpdateContentAssetLinksInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterfaceFactory; + +/** + * Observe the catalog_product_save_after event and run processing relation between product content and media asset + */ +class Product implements ObserverInterface +{ + private const CONTENT_TYPE = 'catalog_product'; + private const TYPE = 'entityType'; + private const ENTITY_ID = 'entityId'; + private const FIELD = 'field'; + + /** + * @var UpdateContentAssetLinksInterface + */ + private $processor; + + /** + * @var array + */ + private $fields; + + /** + * @var ContentIdentityInterfaceFactory + */ + private $contentIdentityFactory; + + /** + * @param ContentIdentityInterfaceFactory $contentIdentityFactory + * @param UpdateContentAssetLinksInterface $processor + * @param array $fields + */ + public function __construct( + ContentIdentityInterfaceFactory $contentIdentityFactory, + UpdateContentAssetLinksInterface $processor, + array $fields + ) { + $this->contentIdentityFactory = $contentIdentityFactory; + $this->processor = $processor; + $this->fields = $fields; + } + + /** + * Retrieve the saved product and pass it to the model processor to save content - asset relations + * + * @param Observer $observer + */ + public function execute(Observer $observer): void + { + $model = $observer->getEvent()->getData('product'); + + if ($model instanceof CatalogProduct) { + foreach ($this->fields as $field) { + if (!$model->dataHasChangedFor($field)) { + continue; + } + + $this->processor->execute( + $this->contentIdentityFactory->create( + [ + self::TYPE => self::CONTENT_TYPE, + self::FIELD => $field, + self::ENTITY_ID => (string) $model->getId(), + ] + ), + (string) $model->getData($field) + ); + } + } + } +} diff --git a/app/code/Magento/MediaContentCatalog/README.md b/app/code/Magento/MediaContentCatalog/README.md new file mode 100644 index 0000000000000..359126a8b7a13 --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/README.md @@ -0,0 +1,13 @@ +# Magento_MediaContentCatalog module + +The Magento_MediaContentCatalog provides the implementation of MediaContent functionality for Magento_Catalog module + +## Extensibility + +Extension developers can interact with the Magento_MediaContent module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). + +[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_MediaContent module. + +## Additional information + +For information about significant changes in patch releases, see [2.3.x Release information](https://devdocs.magento.com/guides/v2.3/release-notes/bk-release-notes.html). diff --git a/app/code/Magento/MediaContentCatalog/composer.json b/app/code/Magento/MediaContentCatalog/composer.json new file mode 100644 index 0000000000000..9efe7aadba041 --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/composer.json @@ -0,0 +1,23 @@ +{ + "name": "magento/module-media-content-catalog", + "description": "Magento module provides the implementation of MediaContent functionality for Magento_Catalog module", + "require": { + "php": "~7.1.3||~7.2.0||~7.3.0", + "magento/module-media-content-api": "*", + "magento/module-catalog": "*", + "magento/framework": "*" + }, + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\MediaContentCatalog\\": "" + } + } +} diff --git a/app/code/Magento/MediaContentCatalog/etc/di.xml b/app/code/Magento/MediaContentCatalog/etc/di.xml new file mode 100644 index 0000000000000..b61b9c1df5f1f --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/etc/di.xml @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\MediaContentCatalog\Observer\Category"> + <arguments> + <argument name="fields" xsi:type="array"> + <item name="image" xsi:type="string">image</item> + <item name="description" xsi:type="string">description</item> + </argument> + </arguments> + </type> + <type name="Magento\MediaContentCatalog\Observer\Product"> + <arguments> + <argument name="fields" xsi:type="array"> + <item name="description" xsi:type="string">description</item> + <item name="short_description" xsi:type="string">short_description</item> + </argument> + </arguments> + </type> +</config> diff --git a/app/code/Magento/MediaContentCatalog/etc/events.xml b/app/code/Magento/MediaContentCatalog/etc/events.xml new file mode 100644 index 0000000000000..f68d66eb3cc40 --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/etc/events.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> + <event name="catalog_category_save_after"> + <observer name="media_content_catalog_category_save_after" instance="Magento\MediaContentCatalog\Observer\Category" /> + </event> + <event name="catalog_product_save_after"> + <observer name="media_content_catalog_product_save_after" instance="Magento\MediaContentCatalog\Observer\Product" /> + </event> +</config> diff --git a/app/code/Magento/MediaContentCatalog/etc/media_content.xml b/app/code/Magento/MediaContentCatalog/etc/media_content.xml new file mode 100644 index 0000000000000..5277462268acb --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/etc/media_content.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_MediaContentApi:etc/media_content.xsd"> + <search> + <patterns> + <pattern name="catalog_image">/^\/?media\/(.*)/</pattern> + </patterns> + </search> +</config> \ No newline at end of file diff --git a/app/code/Magento/AuthorizenetCardinal/etc/module.xml b/app/code/Magento/MediaContentCatalog/etc/module.xml similarity index 56% rename from app/code/Magento/AuthorizenetCardinal/etc/module.xml rename to app/code/Magento/MediaContentCatalog/etc/module.xml index fdf8151311f43..9b863edd57e5e 100644 --- a/app/code/Magento/AuthorizenetCardinal/etc/module.xml +++ b/app/code/Magento/MediaContentCatalog/etc/module.xml @@ -6,10 +6,5 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_AuthorizenetCardinal" > - <sequence> - <module name="Magento_AuthorizenetAcceptjs"/> - <module name="Magento_CardinalCommerce"/> - </sequence> - </module> + <module name="Magento_MediaContentCatalog" /> </config> diff --git a/app/code/Magento/MediaContentCatalog/registration.php b/app/code/Magento/MediaContentCatalog/registration.php new file mode 100644 index 0000000000000..e954285921cba --- /dev/null +++ b/app/code/Magento/MediaContentCatalog/registration.php @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_MediaContentCatalog', __DIR__); diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/LICENSE.txt b/app/code/Magento/MediaContentCms/LICENSE.txt similarity index 100% rename from app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/LICENSE.txt rename to app/code/Magento/MediaContentCms/LICENSE.txt diff --git a/app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/LICENSE_AFL.txt b/app/code/Magento/MediaContentCms/LICENSE_AFL.txt similarity index 100% rename from app/code/Magento/AuthorizenetAcceptjs/Test/Mftf/LICENSE_AFL.txt rename to app/code/Magento/MediaContentCms/LICENSE_AFL.txt diff --git a/app/code/Magento/MediaContentCms/Observer/Block.php b/app/code/Magento/MediaContentCms/Observer/Block.php new file mode 100644 index 0000000000000..ccd1abb98bc60 --- /dev/null +++ b/app/code/Magento/MediaContentCms/Observer/Block.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContentCms\Observer; + +use Magento\Cms\Model\Block as CmsBlock; +use Magento\Framework\Event\Observer; +use Magento\Framework\Event\ObserverInterface; +use Magento\MediaContentApi\Api\UpdateContentAssetLinksInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterfaceFactory; + +/** + * Observe cms_block_save_after event and run processing relation between cms block content and media asset + */ +class Block implements ObserverInterface +{ + private const CONTENT_TYPE = 'cms_block'; + private const TYPE = 'entityType'; + private const ENTITY_ID = 'entityId'; + private const FIELD = 'field'; + + /** + * @var UpdateContentAssetLinksInterface + */ + private $updateContentAssetLinks; + + /** + * @var array + */ + private $fields; + + /** + * @var ContentIdentityInterfaceFactory + */ + private $contentIdentityFactory; + + /** + * @param ContentIdentityInterfaceFactory $contentIdentityFactory + * @param UpdateContentAssetLinksInterface $updateContentAssetLinks + * @param array $fields + */ + public function __construct( + ContentIdentityInterfaceFactory $contentIdentityFactory, + UpdateContentAssetLinksInterface $updateContentAssetLinks, + array $fields + ) { + $this->contentIdentityFactory = $contentIdentityFactory; + $this->updateContentAssetLinks = $updateContentAssetLinks; + $this->fields = $fields; + } + + /** + * Retrieve the saved block and pass it to the model processor to save content - asset relations + * + * @param Observer $observer + */ + public function execute(Observer $observer): void + { + $model = $observer->getEvent()->getData('object'); + + if ($model instanceof CmsBlock) { + foreach ($this->fields as $field) { + if (!$model->dataHasChangedFor($field)) { + continue; + } + $this->updateContentAssetLinks->execute( + $this->contentIdentityFactory->create( + [ + self::TYPE => self::CONTENT_TYPE, + self::FIELD => $field, + self::ENTITY_ID => (string) $model->getId(), + ] + ), + (string) $model->getData($field) + ); + } + } + } +} diff --git a/app/code/Magento/MediaContentCms/Observer/Page.php b/app/code/Magento/MediaContentCms/Observer/Page.php new file mode 100644 index 0000000000000..4c0ed5c628d1c --- /dev/null +++ b/app/code/Magento/MediaContentCms/Observer/Page.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaContentCms\Observer; + +use Magento\Cms\Model\Page as CmsPage; +use Magento\Framework\Event\Observer; +use Magento\Framework\Event\ObserverInterface; +use Magento\MediaContentApi\Api\UpdateContentAssetLinksInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterfaceFactory; + +/** + * Observe cms_page_save_after event and run processing relation between cms page content and media asset. + */ +class Page implements ObserverInterface +{ + private const CONTENT_TYPE = 'cms_page'; + private const TYPE = 'entityType'; + private const ENTITY_ID = 'entityId'; + private const FIELD = 'field'; + + /** + * @var UpdateContentAssetLinksInterface + */ + private $updateContentAssetLinks; + + /** + * @var array + */ + private $fields; + + /** + * @var ContentIdentityInterfaceFactory + */ + private $contentIdentityFactory; + + /** + * @param ContentIdentityInterfaceFactory $contentIdentityFactory + * @param UpdateContentAssetLinksInterface $updateContentAssetLinks + * @param array $fields + */ + public function __construct( + ContentIdentityInterfaceFactory $contentIdentityFactory, + UpdateContentAssetLinksInterface $updateContentAssetLinks, + array $fields + ) { + $this->contentIdentityFactory = $contentIdentityFactory; + $this->updateContentAssetLinks = $updateContentAssetLinks; + $this->fields = $fields; + } + + /** + * Retrieve the saved page and pass it to the model processor to save content - asset relations + * + * @param Observer $observer + */ + public function execute(Observer $observer): void + { + $model = $observer->getEvent()->getData('object'); + + if ($model instanceof CmsPage) { + foreach ($this->fields as $field) { + if (!$model->dataHasChangedFor($field)) { + continue; + } + $this->updateContentAssetLinks->execute( + $this->contentIdentityFactory->create( + [ + self::TYPE => self::CONTENT_TYPE, + self::FIELD => $field, + self::ENTITY_ID => (string) $model->getId(), + ] + ), + (string) $model->getData($field) + ); + } + } + } +} diff --git a/app/code/Magento/MediaContentCms/README.md b/app/code/Magento/MediaContentCms/README.md new file mode 100644 index 0000000000000..32b0fdc2bbd2f --- /dev/null +++ b/app/code/Magento/MediaContentCms/README.md @@ -0,0 +1,13 @@ +# Magento_MediaContentCms module + +The Magento_MediaContentCms provides the implementation of MediaContent functionality for Magento_Cms module + +## Extensibility + +Extension developers can interact with the Magento_MediaContent module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). + +[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_MediaContent module. + +## Additional information + +For information about significant changes in patch releases, see [2.3.x Release information](https://devdocs.magento.com/guides/v2.3/release-notes/bk-release-notes.html). diff --git a/app/code/Magento/MediaContentCms/composer.json b/app/code/Magento/MediaContentCms/composer.json new file mode 100644 index 0000000000000..318027d87a44b --- /dev/null +++ b/app/code/Magento/MediaContentCms/composer.json @@ -0,0 +1,23 @@ +{ + "name": "magento/module-media-content-cms", + "description": "Magento module provides the implementation of MediaContent functionality for Magento_Cms module", + "require": { + "php": "~7.1.3||~7.2.0||~7.3.0", + "magento/module-media-content-api": "*", + "magento/module-cms": "*", + "magento/framework": "*" + }, + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\MediaContentApi\\": "" + } + } +} diff --git a/app/code/Magento/MediaContentCms/etc/di.xml b/app/code/Magento/MediaContentCms/etc/di.xml new file mode 100644 index 0000000000000..f980936465faf --- /dev/null +++ b/app/code/Magento/MediaContentCms/etc/di.xml @@ -0,0 +1,23 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\MediaContentCms\Observer\Block"> + <arguments> + <argument name="fields" xsi:type="array"> + <item name="content" xsi:type="string">content</item> + </argument> + </arguments> + </type> + <type name="Magento\MediaContentCms\Observer\Page"> + <arguments> + <argument name="fields" xsi:type="array"> + <item name="content" xsi:type="string">content</item> + </argument> + </arguments> + </type> +</config> diff --git a/app/code/Magento/MediaContentCms/etc/events.xml b/app/code/Magento/MediaContentCms/etc/events.xml new file mode 100644 index 0000000000000..7e9abe3bf19c4 --- /dev/null +++ b/app/code/Magento/MediaContentCms/etc/events.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> + <event name="cms_page_save_after"> + <observer name="media_content_cms_page_save_after" instance="Magento\MediaContentCms\Observer\Page" /> + </event> + <event name="cms_block_save_after"> + <observer name="media_content_cms_block_save_after" instance="Magento\MediaContentCms\Observer\Block" /> + </event> +</config> diff --git a/app/code/Magento/MediaContentCms/etc/media_content.xml b/app/code/Magento/MediaContentCms/etc/media_content.xml new file mode 100644 index 0000000000000..c0f41d1092134 --- /dev/null +++ b/app/code/Magento/MediaContentCms/etc/media_content.xml @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_MediaContentApi:etc/media_content.xsd"> + <search> + <patterns> + <pattern name="media_gallery">/{{media url="?(.*?)"?}}/</pattern> + <pattern name="wysiwyg">/src=".*\/media\/(.*?)"/</pattern> + </patterns> + </search> +</config> \ No newline at end of file diff --git a/app/code/Magento/Authorizenet/etc/module.xml b/app/code/Magento/MediaContentCms/etc/module.xml similarity index 55% rename from app/code/Magento/Authorizenet/etc/module.xml rename to app/code/Magento/MediaContentCms/etc/module.xml index a30fd34927746..868a6d96fdf51 100644 --- a/app/code/Magento/Authorizenet/etc/module.xml +++ b/app/code/Magento/MediaContentCms/etc/module.xml @@ -6,11 +6,5 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Authorizenet" > - <sequence> - <module name="Magento_Sales"/> - <module name="Magento_Quote"/> - <module name="Magento_Checkout"/> - </sequence> - </module> + <module name="Magento_MediaContentCms"/> </config> diff --git a/app/code/Magento/AuthorizenetCardinal/registration.php b/app/code/Magento/MediaContentCms/registration.php similarity index 80% rename from app/code/Magento/AuthorizenetCardinal/registration.php rename to app/code/Magento/MediaContentCms/registration.php index 7d663df3c3e3a..b231ce3c6f3de 100644 --- a/app/code/Magento/AuthorizenetCardinal/registration.php +++ b/app/code/Magento/MediaContentCms/registration.php @@ -3,7 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_AuthorizenetCardinal', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_MediaContentCms', __DIR__); diff --git a/app/code/Magento/MediaGallery/Model/Asset.php b/app/code/Magento/MediaGallery/Model/Asset.php index 8e232ff0336d9..78b9477a70b08 100644 --- a/app/code/Magento/MediaGallery/Model/Asset.php +++ b/app/code/Magento/MediaGallery/Model/Asset.php @@ -10,36 +10,113 @@ use Magento\MediaGalleryApi\Api\Data\AssetExtensionInterface; use Magento\MediaGalleryApi\Api\Data\AssetInterface; -use Magento\Framework\Model\AbstractExtensibleModel; /** * Media Gallery Asset + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ -class Asset extends AbstractExtensibleModel implements AssetInterface +class Asset implements AssetInterface { - private const ID = 'id'; - private const PATH = 'path'; - private const TITLE = 'title'; - private const SOURCE = 'source'; - private const CONTENT_TYPE = 'content_type'; - private const WIDTH = 'width'; - private const HEIGHT = 'height'; - private const SIZE = 'size'; - private const CREATED_AT = 'created_at'; - private const UPDATED_AT = 'updated_at'; + /** + * @var int|null + */ + private $id; + + /** + * @var string + */ + private $path; + + /** + * @var string|null + */ + private $title; + + /** + * @var string|null + */ + private $source; + + /** + * @var string + */ + private $contentType; + + /** + * @var int + */ + private $width; + + /** + * @var int + */ + private $height; + + /** + * @var int + */ + private $size; + + /** + * @var string|null + */ + private $createdAt; + + /** + * @var string|null + */ + private $updatedAt; + + /** + * @var AssetExtensionInterface|null + */ + private $extensionAttributes; + + /** + * @param string $path + * @param string $contentType + * @param int $width + * @param int $height + * @param int $size + * @param int|null $id + * @param string|null $title + * @param string|null $source + * @param string|null $createdAt + * @param string|null $updatedAt + * @param AssetExtensionInterface|null $extensionAttributes + */ + public function __construct( + string $path, + string $contentType, + int $width, + int $height, + int $size, + ?int $id = null, + ?string $title = null, + ?string $source = null, + ?string $createdAt = null, + ?string $updatedAt = null, + ?AssetExtensionInterface $extensionAttributes = null + ) { + $this->path = $path; + $this->contentType = $contentType; + $this->width = $width; + $this->height = $height; + $this->size = $size; + $this->id = $id; + $this->title = $title; + $this->source = $source; + $this->createdAt = $createdAt; + $this->updatedAt = $updatedAt; + $this->extensionAttributes = $extensionAttributes; + } /** * @inheritdoc */ public function getId(): ?int { - $id = $this->getData(self::ID); - - if (!$id) { - return null; - } - - return (int) $id; + return $this->id; } /** @@ -47,7 +124,7 @@ public function getId(): ?int */ public function getPath(): string { - return (string) $this->getData(self::PATH); + return $this->path; } /** @@ -55,7 +132,7 @@ public function getPath(): string */ public function getTitle(): ?string { - return $this->getData(self::TITLE); + return $this->title; } /** @@ -63,7 +140,7 @@ public function getTitle(): ?string */ public function getSource(): ?string { - return $this->getData(self::SOURCE); + return $this->source; } /** @@ -71,7 +148,7 @@ public function getSource(): ?string */ public function getContentType(): string { - return (string) $this->getData(self::CONTENT_TYPE); + return $this->contentType; } /** @@ -79,7 +156,7 @@ public function getContentType(): string */ public function getWidth(): int { - return (int) $this->getData(self::WIDTH); + return $this->width; } /** @@ -87,7 +164,7 @@ public function getWidth(): int */ public function getHeight(): int { - return (int) $this->getData(self::HEIGHT); + return $this->height; } /** @@ -95,38 +172,38 @@ public function getHeight(): int */ public function getSize(): int { - return (int) $this->getData(self::SIZE); + return $this->size; } /** * @inheritdoc */ - public function getCreatedAt(): string + public function getCreatedAt(): ?string { - return (string) $this->getData(self::CREATED_AT); + return $this->createdAt; } /** * @inheritdoc */ - public function getUpdatedAt(): string + public function getUpdatedAt(): ?string { - return (string) $this->getData(self::UPDATED_AT); + return $this->updatedAt; } /** * @inheritdoc */ - public function getExtensionAttributes(): AssetExtensionInterface + public function getExtensionAttributes(): ?AssetExtensionInterface { - return $this->_getExtensionAttributes(); + return $this->extensionAttributes; } /** * @inheritdoc */ - public function setExtensionAttributes(AssetExtensionInterface $extensionAttributes): void + public function setExtensionAttributes(?AssetExtensionInterface $extensionAttributes): void { - $this->_setExtensionAttributes($extensionAttributes); + $this->extensionAttributes = $extensionAttributes; } } diff --git a/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByDirectoryPath.php b/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByDirectoryPath.php index a50095fb3d8e7..3abe4cb50f2ea 100644 --- a/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByDirectoryPath.php +++ b/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByDirectoryPath.php @@ -14,9 +14,9 @@ use Psr\Log\LoggerInterface; /** - * Class DeleteByDirectoryPath - * * Remove asset(s) that correspond the provided directory path + * @deprecated use \Magento\MediaGalleryApi\Api\DeleteAssetsByPathInterface instead + * @see \Magento\MediaGalleryApi\Api\DeleteAssetsByPathInterfac */ class DeleteByDirectoryPath implements DeleteByDirectoryPathInterface { diff --git a/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByPath.php b/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByPath.php index c05a08149bfca..fc8e5d7c84bfd 100644 --- a/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByPath.php +++ b/app/code/Magento/MediaGallery/Model/Asset/Command/DeleteByPath.php @@ -14,7 +14,10 @@ use Psr\Log\LoggerInterface; /** - * Class DeleteByPath + * Delete media asset by path + * + * @deprecated use \Magento\MediaGalleryApi\Api\DeleteAssetsByPathInterface instead + * @see \Magento\MediaGalleryApi\Api\DeleteAssetsByPathInterface */ class DeleteByPath implements DeleteByPathInterface { diff --git a/app/code/Magento/MediaGallery/Model/Asset/Command/GetById.php b/app/code/Magento/MediaGallery/Model/Asset/Command/GetById.php index 6be11610ac197..b2f900233e46a 100644 --- a/app/code/Magento/MediaGallery/Model/Asset/Command/GetById.php +++ b/app/code/Magento/MediaGallery/Model/Asset/Command/GetById.php @@ -16,7 +16,9 @@ use Psr\Log\LoggerInterface; /** - * Class GetById + * Get media asset by id + * @deprecated use \Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface instead + * @see \Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface */ class GetById implements GetByIdInterface { @@ -28,7 +30,7 @@ class GetById implements GetByIdInterface private $resourceConnection; /** - * @var AssetInterface + * @var AssetInterfaceFactory */ private $assetFactory; @@ -87,7 +89,20 @@ public function execute(int $mediaAssetId): AssetInterface } try { - return $this->assetFactory->create(['data' => $mediaAssetData]); + return $this->assetFactory->create( + [ + 'id' => $mediaAssetData['id'], + 'path' => $mediaAssetData['path'], + 'title' => $mediaAssetData['title'], + 'source' => $mediaAssetData['source'], + 'contentType' => $mediaAssetData['content_type'], + 'width' => $mediaAssetData['width'], + 'height' => $mediaAssetData['height'], + 'size' => $mediaAssetData['size'], + 'createdAt' => $mediaAssetData['created_at'], + 'updatedAt' => $mediaAssetData['updated_at'], + ] + ); } catch (\Exception $exception) { $this->logger->critical($exception); $message = __( diff --git a/app/code/Magento/MediaGallery/Model/Asset/Command/GetByPath.php b/app/code/Magento/MediaGallery/Model/Asset/Command/GetByPath.php index db8482d3399ba..d9faad62b2cd1 100644 --- a/app/code/Magento/MediaGallery/Model/Asset/Command/GetByPath.php +++ b/app/code/Magento/MediaGallery/Model/Asset/Command/GetByPath.php @@ -16,7 +16,10 @@ use Psr\Log\LoggerInterface; /** - * Class GetListByIds + * Provide media asset by path + * + * @deprecated use \Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface instead + * @see \Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface */ class GetByPath implements GetByPathInterface { @@ -30,7 +33,7 @@ class GetByPath implements GetByPathInterface private $resourceConnection; /** - * @var AssetInterface + * @var AssetInterfaceFactory */ private $mediaAssetFactory; @@ -57,30 +60,41 @@ public function __construct( } /** - * Return media asset asset list + * Return media asset * - * @param string $mediaFilePath + * @param string $path * * @return AssetInterface * @throws IntegrationException */ - public function execute(string $mediaFilePath): AssetInterface + public function execute(string $path): AssetInterface { try { $connection = $this->resourceConnection->getConnection(); $select = $connection->select() ->from($this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET)) - ->where(self::MEDIA_GALLERY_ASSET_PATH . ' = ?', $mediaFilePath); + ->where(self::MEDIA_GALLERY_ASSET_PATH . ' = ?', $path); $data = $connection->query($select)->fetch(); if (empty($data)) { - $message = __('There is no such media asset with path "%1"', $mediaFilePath); + $message = __('There is no such media asset with path "%1"', $path); throw new NoSuchEntityException($message); } - $mediaAssets = $this->mediaAssetFactory->create(['data' => $data]); - - return $mediaAssets; + return $this->mediaAssetFactory->create( + [ + 'id' => $data['id'], + 'path' => $data['path'], + 'title' => $data['title'], + 'source' => $data['source'], + 'contentType' => $data['content_type'], + 'width' => $data['width'], + 'height' => $data['height'], + 'size' => $data['size'], + 'createdAt' => $data['created_at'], + 'updatedAt' => $data['updated_at'], + ] + ); } catch (\Exception $exception) { $this->logger->critical($exception); $message = __('An error occurred during get media asset list: %1', $exception->getMessage()); diff --git a/app/code/Magento/MediaGallery/Model/Asset/Command/Save.php b/app/code/Magento/MediaGallery/Model/Asset/Command/Save.php index 7cb2f73169642..1710176c1b3af 100644 --- a/app/code/Magento/MediaGallery/Model/Asset/Command/Save.php +++ b/app/code/Magento/MediaGallery/Model/Asset/Command/Save.php @@ -7,15 +7,17 @@ namespace Magento\MediaGallery\Model\Asset\Command; -use Magento\MediaGalleryApi\Model\DataExtractorInterface; -use Magento\MediaGalleryApi\Api\Data\AssetInterface; -use Magento\MediaGalleryApi\Model\Asset\Command\SaveInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\Exception\CouldNotSaveException; +use Magento\MediaGalleryApi\Api\Data\AssetInterface; +use Magento\MediaGalleryApi\Model\Asset\Command\SaveInterface; use Psr\Log\LoggerInterface; /** - * Class Save + * Save media asset + * + * @deprecated use \Magento\MediaGalleryApi\Api\SaveAssetsInterface instead + * @see \Magento\MediaGalleryApi\Api\SaveAssetsInterface */ class Save implements SaveInterface { @@ -26,11 +28,6 @@ class Save implements SaveInterface */ private $resourceConnection; - /** - * @var DataExtractorInterface - */ - private $extractor; - /** * @var LoggerInterface */ @@ -40,21 +37,18 @@ class Save implements SaveInterface * Save constructor. * * @param ResourceConnection $resourceConnection - * @param DataExtractorInterface $extractor * @param LoggerInterface $logger */ public function __construct( ResourceConnection $resourceConnection, - DataExtractorInterface $extractor, LoggerInterface $logger ) { $this->resourceConnection = $resourceConnection; - $this->extractor = $extractor; $this->logger = $logger; } /** - * Save media assets + * Save media asset * * @param AssetInterface $mediaAsset * @@ -67,9 +61,27 @@ public function execute(AssetInterface $mediaAsset): int /** @var \Magento\Framework\DB\Adapter\Pdo\Mysql $connection */ $connection = $this->resourceConnection->getConnection(); $tableName = $this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET); + $record = [ + 'id' => $mediaAsset->getId(), + 'path' => $mediaAsset->getPath(), + 'title' => $mediaAsset->getTitle(), + 'source' => $mediaAsset->getSource(), + 'content_type' => $mediaAsset->getContentType(), + 'width' => $mediaAsset->getWidth(), + 'height' => $mediaAsset->getHeight(), + 'size' => $mediaAsset->getSize(), + ]; + + if ($mediaAsset->getCreatedAt()) { + $record['created_at'] = $mediaAsset->getCreatedAt(); + } + + if ($mediaAsset->getUpdatedAt()) { + $record['updated_at'] = $mediaAsset->getUpdatedAt(); + } - $connection->insertOnDuplicate($tableName, $this->extractor->extract($mediaAsset, AssetInterface::class)); - return (int) $connection->lastInsertId($tableName); + $connection->insertOnDuplicate($tableName, $record); + return (int)$connection->lastInsertId($tableName); } catch (\Exception $exception) { $this->logger->critical($exception); $message = __('An error occurred during media asset save: %1', $exception->getMessage()); diff --git a/app/code/Magento/MediaGallery/Model/AssetKeywords.php b/app/code/Magento/MediaGallery/Model/AssetKeywords.php new file mode 100644 index 0000000000000..4ffea9551263c --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/AssetKeywords.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model; + +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface; +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsExtensionInterface; + +/** + * Asset Id and Keywords combination data object for bulk operations with keyword services + */ +class AssetKeywords implements AssetKeywordsInterface +{ + /** + * @var int + */ + private $assetId; + + /** + * @var array + */ + private $keywords; + + /** + * @var AssetKeywordsExtensionInterface|null + */ + private $extensionAttributes; + + /** + * @param int $assetId + * @param array $keywords + * @param AssetKeywordsExtensionInterface|null $extensionAttributes + */ + public function __construct( + int $assetId, + array $keywords, + ?AssetKeywordsExtensionInterface $extensionAttributes = null + ) { + $this->assetId = $assetId; + $this->keywords = $keywords; + $this->extensionAttributes = $extensionAttributes; + } + + /** + * @inheritdoc + */ + public function getAssetId(): int + { + return $this->assetId; + } + + /** + * @inheritdoc + */ + public function getKeywords(): array + { + return $this->keywords; + } + + /** + * @inheritdoc + */ + public function getExtensionAttributes(): ?AssetKeywordsExtensionInterface + { + return $this->extensionAttributes; + } + + /** + * @inheritdoc + */ + public function setExtensionAttributes(?AssetKeywordsExtensionInterface $extensionAttributes): void + { + $this->extensionAttributes = $extensionAttributes; + } +} diff --git a/app/code/Magento/MediaGallery/Model/DataExtractor.php b/app/code/Magento/MediaGallery/Model/DataExtractor.php deleted file mode 100644 index 92cf237022c28..0000000000000 --- a/app/code/Magento/MediaGallery/Model/DataExtractor.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\MediaGallery\Model; - -use Magento\MediaGalleryApi\Model\DataExtractorInterface; - -/** - * Extract data from an object using available getters - */ -class DataExtractor implements DataExtractorInterface -{ - /** - * Extract data from an object using available getters (does not process extension attributes) - * - * @param object $object - * @param string|null $interface - * - * @return array - * @throws \ReflectionException - */ - public function extract($object, string $interface = null): array - { - $data = []; - - $reflectionClass = new \ReflectionClass($interface ?? $object); - - foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { - $methodName = $method->getName(); - if (strpos($methodName, 'get') !== 0 - || !empty($method->getParameters()) - || strpos($methodName, 'getExtensionAttributes') !== false - ) { - continue; - } - $value = $object->$methodName(); - if (!empty($value)) { - $key = strtolower(preg_replace("/([a-z])([A-Z])/", "$1_$2", substr($methodName, 3))); - $data[$key] = $value; - } - } - return $data; - } -} diff --git a/app/code/Magento/MediaGallery/Model/Directory/BlacklistPatternsConfig.php b/app/code/Magento/MediaGallery/Model/Directory/BlacklistPatternsConfig.php new file mode 100644 index 0000000000000..8fdd4f70d5060 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/Directory/BlacklistPatternsConfig.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory; + +use Magento\Framework\Config\DataInterface; +use Magento\MediaGalleryApi\Model\BlacklistPatternsConfigInterface; + +/** + * Media gallery directory config + */ +class BlacklistPatternsConfig implements BlacklistPatternsConfigInterface +{ + private const XML_PATH_BLACKLIST_PATTERNS = 'blacklist/patterns'; + + /** + * @var DataInterface + */ + private $data; + + /** + * @param DataInterface $data + */ + public function __construct(DataInterface $data) + { + $this->data = $data; + } + + /** + * Returns list of blacklist regexp patterns + * + * @return array + */ + public function get() : array + { + return $this->data->get(self::XML_PATH_BLACKLIST_PATTERNS); + } +} diff --git a/app/code/Magento/MediaGallery/Model/Directory/Command/CreateByPaths.php b/app/code/Magento/MediaGallery/Model/Directory/Command/CreateByPaths.php new file mode 100644 index 0000000000000..bfb6b677ce19c --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/Directory/Command/CreateByPaths.php @@ -0,0 +1,89 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory\Command; + +use Magento\Cms\Model\Wysiwyg\Images\Storage; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\MediaGalleryApi\Api\CreateDirectoriesByPathsInterface; +use Magento\MediaGalleryApi\Api\IsPathBlacklistedInterface; +use Psr\Log\LoggerInterface; + +/** + * Create directories by provided paths in the media storage + */ +class CreateByPaths implements CreateDirectoriesByPathsInterface +{ + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var Storage + */ + private $storage; + + /** + * @var IsPathBlacklistedInterface + */ + private $isPathBlacklisted; + + /** + * @param LoggerInterface $logger + * @param Storage $storage + * @param IsPathBlacklistedInterface $isPathBlacklisted + */ + public function __construct( + LoggerInterface $logger, + Storage $storage, + IsPathBlacklistedInterface $isPathBlacklisted + ) { + $this->logger = $logger; + $this->storage = $storage; + $this->isPathBlacklisted = $isPathBlacklisted; + } + + /** + * @inheritdoc + */ + public function execute(array $paths): void + { + $failedPaths = []; + foreach ($paths as $path) { + if ($this->isPathBlacklisted->execute($path)) { + $failedPaths[] = $path; + continue; + } + try { + //phpcs:ignore Magento2.Functions.DiscouragedFunction + $name = basename($path); + //phpcs:ignore Magento2.Functions.DiscouragedFunction + $folder = str_replace($name, '', $path); + + $this->storage->createDirectory( + $name, + $this->storage->getCmsWysiwygImages()->getStorageRoot() . $folder + ); + } catch (\Exception $exception) { + $this->logger->critical($exception); + $failedPaths[] = $path; + } + } + + if (!empty($failedPaths)) { + throw new CouldNotSaveException( + __( + 'Could not save directories: %paths', + [ + 'paths' => implode(' ,', $failedPaths) + ] + ) + ); + } + } +} diff --git a/app/code/Magento/MediaGallery/Model/Directory/Command/DeleteByPaths.php b/app/code/Magento/MediaGallery/Model/Directory/Command/DeleteByPaths.php new file mode 100644 index 0000000000000..d46fb854fff22 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/Directory/Command/DeleteByPaths.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory\Command; + +use Magento\Cms\Model\Wysiwyg\Images\Storage; +use Magento\Framework\Exception\CouldNotDeleteException; +use Magento\MediaGalleryApi\Api\DeleteDirectoriesByPathsInterface; +use Magento\MediaGalleryApi\Api\IsPathBlacklistedInterface; +use Psr\Log\LoggerInterface; + +/** + * Delete directory by provided paths in the media storage + */ +class DeleteByPaths implements DeleteDirectoriesByPathsInterface +{ + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var Storage + */ + private $storage; + + /** + * @var IsPathBlacklistedInterface + */ + private $isPathBlacklisted; + + /** + * @param LoggerInterface $logger + * @param Storage $storage + * @param IsPathBlacklistedInterface $isPathBlacklisted + */ + public function __construct( + LoggerInterface $logger, + Storage $storage, + IsPathBlacklistedInterface $isPathBlacklisted + ) { + $this->logger = $logger; + $this->storage = $storage; + $this->isPathBlacklisted = $isPathBlacklisted; + } + + /** + * @inheritdoc + */ + public function execute(array $paths): void + { + $failedPaths = []; + foreach ($paths as $path) { + if ($this->isPathBlacklisted->execute($path)) { + $failedPaths[] = $path; + continue; + } + try { + $this->storage->deleteDirectory($this->storage->getCmsWysiwygImages()->getStorageRoot() . $path); + } catch (\Exception $exception) { + $this->logger->critical($exception); + $failedPaths[] = $path; + } + } + + if (!empty($failedPaths)) { + throw new CouldNotDeleteException( + __( + 'Could not delete directories: %paths', + [ + 'paths' => implode(' ,', $failedPaths) + ] + ) + ); + } + } +} diff --git a/app/code/Magento/MediaGallery/Model/Directory/Config/Converter.php b/app/code/Magento/MediaGallery/Model/Directory/Config/Converter.php new file mode 100644 index 0000000000000..91f16d246f636 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/Directory/Config/Converter.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory\Config; + +use Magento\Framework\Config\ConverterInterface; + +/** + * Media gallery directory config converter + */ +class Converter implements ConverterInterface +{ + /** + * Blacklist tag name + */ + private const BLACKLIST_TAG_NAME = 'blacklist'; + + /** + * Patterns tag name + */ + private const PATTERNS_TAG_NAME = 'patterns'; + + /** + * Pattern tag name + */ + private const PATTERN_TAG_NAME = 'pattern'; + + /** + * Convert dom node to array + * + * @param \DOMDocument $source + * @return array + */ + public function convert($source): array + { + $result = []; + + if (!$source instanceof \DOMDocument) { + throw new \InvalidArgumentException('The source should be instance of DOMDocument'); + } + + foreach ($source->getElementsByTagName(self::BLACKLIST_TAG_NAME) as $blacklist) { + $result[self::BLACKLIST_TAG_NAME] = []; + foreach ($blacklist->getElementsByTagName(self::PATTERNS_TAG_NAME) as $patterns) { + $result[self::BLACKLIST_TAG_NAME][self::PATTERNS_TAG_NAME] = []; + foreach ($patterns->getElementsByTagName(self::PATTERN_TAG_NAME) as $pattern) { + $result[self::BLACKLIST_TAG_NAME][self::PATTERNS_TAG_NAME] + [$pattern->attributes->getNamedItem('name')->nodeValue] = $pattern->nodeValue; + } + } + } + + return $result; + } +} diff --git a/app/code/Magento/MediaGallery/Model/Directory/Config/SchemaLocator.php b/app/code/Magento/MediaGallery/Model/Directory/Config/SchemaLocator.php new file mode 100644 index 0000000000000..7fdf414cdd228 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/Directory/Config/SchemaLocator.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory\Config; + +use Magento\Framework\Module\Dir; +use Magento\Framework\Module\Dir\Reader; +use Magento\Framework\Config\SchemaLocatorInterface; + +/** + * Media gallery directory config schema locator + */ +class SchemaLocator implements SchemaLocatorInterface +{ + /** + * Path to corresponding XSD file with validation rules for both individual and merged configs + * + * @var string + */ + private $schema; + + /** + * @param Reader $moduleReader + */ + public function __construct(Reader $moduleReader) + { + $this->schema = $moduleReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Magento_MediaGalleryApi') . '/directory.xsd'; + } + + /** + * Get path to merged config schema + * + * @return string|null + */ + public function getSchema() + { + return $this->schema; + } + + /** + * Get path to per file validation schema + * + * @return string|null + */ + public function getPerFileSchema() + { + return $this->schema; + } +} diff --git a/app/code/Magento/MediaGallery/Model/Directory/IsBlacklisted.php b/app/code/Magento/MediaGallery/Model/Directory/IsBlacklisted.php new file mode 100644 index 0000000000000..0191b357aaefa --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/Directory/IsBlacklisted.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory; + +use Magento\MediaGalleryApi\Api\IsPathBlacklistedInterface; +use Magento\MediaGalleryApi\Model\BlacklistPatternsConfigInterface; + +/** + * Check if the path is blacklisted for media gallery. Directory path may be blacklisted if it's reserved by the system + */ +class IsBlacklisted implements IsPathBlacklistedInterface +{ + /** + * @var BlacklistPatternsConfigInterface + */ + private $config; + + /** + * @param BlacklistPatternsConfigInterface $config + */ + public function __construct(BlacklistPatternsConfigInterface $config) + { + $this->config = $config; + } + + /** + * Check if the directory path can be used in the media gallery operations + * + * @param string $path + * @return bool + */ + public function execute(string $path): bool + { + foreach ($this->config->get() as $pattern) { + if (empty($pattern)) { + continue; + } + preg_match($pattern, $path, $result); + + if ($result) { + return true; + } + } + return false; + } +} diff --git a/app/code/Magento/MediaGallery/Model/Keyword.php b/app/code/Magento/MediaGallery/Model/Keyword.php index c5c60d3152846..5d3afd2096a62 100644 --- a/app/code/Magento/MediaGallery/Model/Keyword.php +++ b/app/code/Magento/MediaGallery/Model/Keyword.php @@ -10,29 +10,48 @@ use Magento\MediaGalleryApi\Api\Data\KeywordExtensionInterface; use Magento\MediaGalleryApi\Api\Data\KeywordInterface; -use Magento\Framework\Model\AbstractExtensibleModel; /** * Asset's Keyword */ -class Keyword extends AbstractExtensibleModel implements KeywordInterface +class Keyword implements KeywordInterface { - private const ID = 'id'; + /** + * @var int + */ + private $id; - private const KEYWORD = 'keyword'; + /** + * @var string + */ + private $keyword; + + /** + * @var KeywordExtensionInterface|null + */ + private $extensionAttributes; + + /** + * @param string $keyword + * @param int|null $id + * @param KeywordExtensionInterface|null $extensionAttributes + */ + public function __construct( + string $keyword, + ?int $id = null, + ?KeywordExtensionInterface $extensionAttributes = null + ) { + $this->keyword = $keyword; + $this->id = $id; + $this->extensionAttributes = $extensionAttributes; + } /** * @inheritdoc */ public function getId(): ?int { - $id = $this->getData(self::ID); - - if (!$id) { - return null; - } - - return (int) $id; + return $this->id; } /** @@ -40,22 +59,22 @@ public function getId(): ?int */ public function getKeyword(): string { - return (string)$this->getData(self::KEYWORD); + return $this->keyword; } /** * @inheritdoc */ - public function getExtensionAttributes(): KeywordExtensionInterface + public function getExtensionAttributes(): ?KeywordExtensionInterface { - return $this->_getExtensionAttributes(); + return $this->extensionAttributes; } /** * @inheritdoc */ - public function setExtensionAttributes(KeywordExtensionInterface $extensionAttributes): void + public function setExtensionAttributes(?KeywordExtensionInterface $extensionAttributes): void { - $this->_setExtensionAttributes($extensionAttributes); + $this->extensionAttributes = $extensionAttributes; } } diff --git a/app/code/Magento/MediaGallery/Model/Keyword/Command/GetAssetKeywords.php b/app/code/Magento/MediaGallery/Model/Keyword/Command/GetAssetKeywords.php index 5b826a26e937d..27d32e5444f4b 100644 --- a/app/code/Magento/MediaGallery/Model/Keyword/Command/GetAssetKeywords.php +++ b/app/code/Magento/MediaGallery/Model/Keyword/Command/GetAssetKeywords.php @@ -15,7 +15,8 @@ use Psr\Log\LoggerInterface; /** - * ClassGetAssetKeywords + * Retrieve keywords for the media asset + * @deprecated use \Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface instead */ class GetAssetKeywords implements GetAssetKeywordsInterface { @@ -59,7 +60,7 @@ public function __construct( * * @param int $assetId * - * @return KeywordInterface[]|[] + * @return KeywordInterface[] * @throws IntegrationException */ public function execute(int $assetId): array @@ -75,7 +76,12 @@ public function execute(int $assetId): array $keywords = []; foreach ($data as $keywordData) { - $keywords[] = $this->assetKeywordFactory->create(['data' => $keywordData]); + $keywords[] = $this->assetKeywordFactory->create( + [ + 'id' => $keywordData['id'], + 'keyword' => $keywordData['keyword'], + ] + ); } return $keywords; diff --git a/app/code/Magento/MediaGallery/Model/Keyword/Command/SaveAssetKeywords.php b/app/code/Magento/MediaGallery/Model/Keyword/Command/SaveAssetKeywords.php index b355a9a651cd4..f21db25bac767 100644 --- a/app/code/Magento/MediaGallery/Model/Keyword/Command/SaveAssetKeywords.php +++ b/app/code/Magento/MediaGallery/Model/Keyword/Command/SaveAssetKeywords.php @@ -7,16 +7,18 @@ namespace Magento\MediaGallery\Model\Keyword\Command; -use Magento\MediaGalleryApi\Api\Data\KeywordInterface; -use Magento\MediaGalleryApi\Model\Keyword\Command\SaveAssetKeywordsInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Adapter\Pdo\Mysql; use Magento\Framework\Exception\CouldNotSaveException; +use Magento\MediaGallery\Model\ResourceModel\Keyword\SaveAssetLinks; +use Magento\MediaGalleryApi\Api\Data\KeywordInterface; +use Magento\MediaGalleryApi\Model\Keyword\Command\SaveAssetKeywordsInterface; use Psr\Log\LoggerInterface; /** - * Class SaveAssetKeywords + * Save media asset keywords to database + * @deprecated use \Magento\MediaGalleryApi\Api\SaveAssetKeywordsInterface instead */ class SaveAssetKeywords implements SaveAssetKeywordsInterface { @@ -40,8 +42,6 @@ class SaveAssetKeywords implements SaveAssetKeywordsInterface private $logger; /** - * SaveAssetKeywords constructor. - * * @param ResourceConnection $resourceConnection * @param SaveAssetLinks $saveAssetLinks * @param LoggerInterface $logger diff --git a/app/code/Magento/MediaGallery/Model/ResourceModel/DeleteAssetsByPaths.php b/app/code/Magento/MediaGallery/Model/ResourceModel/DeleteAssetsByPaths.php new file mode 100644 index 0000000000000..031bf25c4e5bb --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/ResourceModel/DeleteAssetsByPaths.php @@ -0,0 +1,102 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Exception\CouldNotDeleteException; +use Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface; +use Psr\Log\LoggerInterface; + +/** + * Remove asset(s) that correspond the provided path + */ +class DeleteAssetsByPaths implements DeleteAssetsByPathsInterface +{ + private const TABLE_MEDIA_GALLERY_ASSET = 'media_gallery_asset'; + private const MEDIA_GALLERY_ASSET_PATH = 'path'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * DeleteById constructor. + * + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct( + ResourceConnection $resourceConnection, + LoggerInterface $logger + ) { + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(array $paths): void + { + $failedPaths = []; + + foreach ($paths as $path) { + try { + $this->validateDirectoryPath($path); + $this->deleteAssetsByDirectoryPath($path); + } catch (\Exception $exception) { + $this->logger->critical($exception); + $failedPaths[] = $path; + } + } + + if (!empty($failedPaths)) { + throw new CouldNotDeleteException( + __( + 'Could not delete media assets by paths: %paths', + [ + 'paths' => implode(' ,', $failedPaths) + ] + ) + ); + } + } + + /** + * Delete assets from database based on the first part (beginning) of the path + * + * @param string $path + */ + private function deleteAssetsByDirectoryPath(string $path): void + { + /** @var AdapterInterface $connection */ + $connection = $this->resourceConnection->getConnection(); + $tableName = $this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET); + $connection->delete($tableName, [self::MEDIA_GALLERY_ASSET_PATH . ' LIKE ?' => $path . '%']); + } + + /** + * Validate the directory path + * + * @param string $path + * @throws CouldNotDeleteException + */ + private function validateDirectoryPath(string $path): void + { + if (!$path || trim($path) === '') { + throw new CouldNotDeleteException(__('Cannot remove assets, the directory path does not exist')); + } + } +} diff --git a/app/code/Magento/MediaGallery/Model/ResourceModel/GetAssetsByIds.php b/app/code/Magento/MediaGallery/Model/ResourceModel/GetAssetsByIds.php new file mode 100644 index 0000000000000..53185939b2283 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/ResourceModel/GetAssetsByIds.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\LocalizedException; +use Magento\MediaGalleryApi\Api\Data\AssetInterfaceFactory; +use Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface; +use Psr\Log\LoggerInterface; + +/** + * Get media assets by ids + */ +class GetAssetsByIds implements GetAssetsByIdsInterface +{ + private const TABLE_MEDIA_GALLERY_ASSET = 'media_gallery_asset'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var AssetInterfaceFactory + */ + private $assetFactory; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * GetById constructor. + * + * @param ResourceConnection $resourceConnection + * @param AssetInterfaceFactory $assetFactory + * @param LoggerInterface $logger + */ + public function __construct( + ResourceConnection $resourceConnection, + AssetInterfaceFactory $assetFactory, + LoggerInterface $logger + ) { + $this->resourceConnection = $resourceConnection; + $this->assetFactory = $assetFactory; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(array $ids): array + { + $assets = []; + try { + foreach ($this->getAssetsData($ids) as $assetData) { + $assets[] = $this->assetFactory->create( + [ + 'id' => $assetData['id'], + 'path' => $assetData['path'], + 'title' => $assetData['title'], + 'source' => $assetData['source'], + 'contentType' => $assetData['content_type'], + 'width' => $assetData['width'], + 'height' => $assetData['height'], + 'size' => $assetData['size'], + 'createdAt' => $assetData['created_at'], + 'updatedAt' => $assetData['updated_at'], + ] + ); + } + } catch (\Exception $exception) { + $this->logger->critical($exception); + throw new LocalizedException(__('Could not retrieve media assets'), $exception); + } + return $assets; + } + + /** + * Retrieve assets data from database + * + * @param array $ids + * @return array + * @throws \Zend_Db_Statement_Exception + */ + private function getAssetsData(array $ids): array + { + $mediaAssetTable = $this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET); + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->from(['amg' => $mediaAssetTable]) + ->where('amg.id IN (?)', $ids); + return $connection->query($select)->fetchAll(); + } +} diff --git a/app/code/Magento/MediaGallery/Model/ResourceModel/GetAssetsByPaths.php b/app/code/Magento/MediaGallery/Model/ResourceModel/GetAssetsByPaths.php new file mode 100644 index 0000000000000..5593083d9673a --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/ResourceModel/GetAssetsByPaths.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Magento\Framework\Exception\LocalizedException; +use Magento\MediaGalleryApi\Api\Data\AssetInterfaceFactory; +use Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface; +use Magento\Framework\App\ResourceConnection; +use Psr\Log\LoggerInterface; + +/** + * Get media assets by paths + */ +class GetAssetsByPaths implements GetAssetsByPathsInterface +{ + private const TABLE_MEDIA_GALLERY_ASSET = 'media_gallery_asset'; + private const MEDIA_GALLERY_ASSET_PATH = 'path'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var AssetInterfaceFactory + */ + private $mediaAssetFactory; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * GetByPath constructor. + * + * @param ResourceConnection $resourceConnection + * @param AssetInterfaceFactory $mediaAssetFactory + * @param LoggerInterface $logger + */ + public function __construct( + ResourceConnection $resourceConnection, + AssetInterfaceFactory $mediaAssetFactory, + LoggerInterface $logger + ) { + $this->resourceConnection = $resourceConnection; + $this->mediaAssetFactory = $mediaAssetFactory; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(array $paths): array + { + $assets = []; + try { + foreach ($this->getAssetsData($paths) as $assetData) { + $assets[] = $this->mediaAssetFactory->create( + [ + 'id' => $assetData['id'], + 'path' => $assetData['path'], + 'title' => $assetData['title'], + 'source' => $assetData['source'], + 'contentType' => $assetData['content_type'], + 'width' => $assetData['width'], + 'height' => $assetData['height'], + 'size' => $assetData['size'], + 'createdAt' => $assetData['created_at'], + 'updatedAt' => $assetData['updated_at'], + ] + ); + } + } catch (\Exception $exception) { + $this->logger->critical($exception); + throw new LocalizedException( + __( + 'Could not get media assets for paths: %paths', + [ + 'paths' => implode(' ,', $paths) + ] + ) + ); + } + return $assets; + } + + /** + * Retrieve assets data from database + * + * @param array $paths + * @return array + * @throws \Zend_Db_Statement_Exception + */ + private function getAssetsData(array $paths): array + { + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->from($this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET)) + ->where(self::MEDIA_GALLERY_ASSET_PATH . ' IN (?)', $paths); + return $connection->query($select)->fetchAll(); + } +} diff --git a/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/GetAssetsKeywords.php b/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/GetAssetsKeywords.php new file mode 100644 index 0000000000000..11b0a0fa3a359 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/GetAssetsKeywords.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel\Keyword; + +use Magento\Framework\Exception\IntegrationException; +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface; +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterfaceFactory; +use Magento\MediaGalleryApi\Api\Data\KeywordInterfaceFactory; +use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface; +use Magento\Framework\App\ResourceConnection; +use Psr\Log\LoggerInterface; + +/** + * Retrieve keywords of the media assets + */ +class GetAssetsKeywords implements GetAssetsKeywordsInterface +{ + private const TABLE_KEYWORD = 'media_gallery_keyword'; + private const TABLE_ASSET_KEYWORD = 'media_gallery_asset_keyword'; + private const FIELD_ASSET_ID = 'asset_id'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var KeywordInterfaceFactory + */ + private $keywordFactory; + + /** + * @var AssetKeywordsInterfaceFactory + */ + private $assetKeywordsFactory; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param AssetKeywordsInterfaceFactory $assetKeywordsFactory + * @param ResourceConnection $resourceConnection + * @param KeywordInterfaceFactory $keywordFactory + * @param LoggerInterface $logger + */ + public function __construct( + AssetKeywordsInterfaceFactory $assetKeywordsFactory, + ResourceConnection $resourceConnection, + KeywordInterfaceFactory $keywordFactory, + LoggerInterface $logger + ) { + $this->assetKeywordsFactory = $assetKeywordsFactory; + $this->resourceConnection = $resourceConnection; + $this->keywordFactory = $keywordFactory; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(array $assetIds): array + { + try { + return $this->getAssetKeywords($this->getKeywordsData($assetIds)); + } catch (\Exception $exception) { + $this->logger->critical($exception); + throw new IntegrationException(__('Could not retrieve asset keywords.'), $exception); + } + } + + /** + * Load keywords data + * + * @param array $assetIds + * @return array + * @throws \Zend_Db_Statement_Exception + */ + private function getKeywordsData(array $assetIds): array + { + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->from(['k' => $this->resourceConnection->getTableName(self::TABLE_KEYWORD)]) + ->join(['ak' => self::TABLE_ASSET_KEYWORD], 'k.id = ak.keyword_id') + ->where('ak.asset_id IN (?)', $assetIds); + return $connection->query($select)->fetchAll(); + } + + /** + * Build AssetKeywords objects array + * + * @param array $keywordsData + * @return AssetKeywordsInterface[] + */ + private function getAssetKeywords(array $keywordsData): array + { + $keywordsByAsset = []; + foreach ($keywordsData as $keywordData) { + $keywordsByAsset[$keywordData[self::FIELD_ASSET_ID]][] = $this->keywordFactory->create( + [ + 'id' => $keywordData['id'], + 'keyword' => $keywordData['keyword'], + ] + ); + } + + $assetKeywords = []; + foreach ($keywordsByAsset as $assetId => $keywords) { + $assetKeywords[$assetId] = $this->assetKeywordsFactory->create( + [ + 'assetId' => $assetId, + 'keywords' => $keywords + ] + ); + } + + return $assetKeywords; + } +} diff --git a/app/code/Magento/MediaGallery/Model/Keyword/Command/SaveAssetLinks.php b/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetLinks.php similarity index 84% rename from app/code/Magento/MediaGallery/Model/Keyword/Command/SaveAssetLinks.php rename to app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetLinks.php index 4d3fd2bb5c30d..3437cc1c519e8 100644 --- a/app/code/Magento/MediaGallery/Model/Keyword/Command/SaveAssetLinks.php +++ b/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetLinks.php @@ -5,18 +5,17 @@ */ declare(strict_types=1); -namespace Magento\MediaGallery\Model\Keyword\Command; +namespace Magento\MediaGallery\Model\ResourceModel\Keyword; -use Magento\MediaGalleryApi\Api\Data\KeywordInterface; -use Magento\MediaGalleryApi\Model\Keyword\Command\SaveAssetLinksInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Adapter\Pdo\Mysql; use Magento\Framework\Exception\CouldNotSaveException; +use Magento\MediaGalleryApi\Api\Data\KeywordInterface; use Psr\Log\LoggerInterface; /** - * Class SaveAssetLinks + * Save links between asset and keyword to media_gallery_asset_keyword table */ class SaveAssetLinks { @@ -35,8 +34,6 @@ class SaveAssetLinks private $logger; /** - * SaveAssetLinks constructor. - * * @param ResourceConnection $resourceConnection * @param LoggerInterface $logger */ @@ -76,8 +73,10 @@ public function execute(int $assetId, array $keywordIds): void } } catch (\Exception $exception) { $this->logger->critical($exception); - $message = __('An error occurred during save asset keyword links: %1', $exception->getMessage()); - throw new CouldNotSaveException($message, $exception); + throw new CouldNotSaveException( + __('Could not save asset keyword links'), + $exception + ); } } } diff --git a/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetsKeywords.php b/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetsKeywords.php new file mode 100644 index 0000000000000..a97c5f602c5c7 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetsKeywords.php @@ -0,0 +1,128 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel\Keyword; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Adapter\Pdo\Mysql; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\MediaGalleryApi\Api\Data\KeywordInterface; +use Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface; +use Psr\Log\LoggerInterface; + +/** + * Save keywords of media assets + */ +class SaveAssetsKeywords implements SaveAssetsKeywordsInterface +{ + private const TABLE_KEYWORD = 'media_gallery_keyword'; + private const ID = 'id'; + private const KEYWORD = 'keyword'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var SaveAssetLinks + */ + private $saveAssetLinks; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * SaveAssetKeywords constructor. + * + * @param ResourceConnection $resourceConnection + * @param SaveAssetLinks $saveAssetLinks + * @param LoggerInterface $logger + */ + public function __construct( + ResourceConnection $resourceConnection, + SaveAssetLinks $saveAssetLinks, + LoggerInterface $logger + ) { + $this->resourceConnection = $resourceConnection; + $this->saveAssetLinks = $saveAssetLinks; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(array $assetKeywords): void + { + $failedAssetIds = []; + foreach ($assetKeywords as $assetKeyword) { + try { + $this->saveAssetKeywords($assetKeyword->getKeywords(), $assetKeyword->getAssetId()); + } catch (\Exception $exception) { + $this->logger->critical($exception); + $failedAssetIds[] = $assetKeyword->getAssetId(); + } + } + + if (!empty($failedAssetIds)) { + throw new CouldNotSaveException( + __('Could not save keywords for asset ids: %ids', ['ids' => implode(' ,', $failedAssetIds)]) + ); + } + } + + /** + * Save asset keywords. + * + * @param KeywordInterface[] $keywords + * @param int $assetId + * @throws CouldNotSaveException + * @throws \Zend_Db_Exception + */ + private function saveAssetKeywords(array $keywords, int $assetId): void + { + $data = []; + foreach ($keywords as $keyword) { + $data[] = $keyword->getKeyword(); + } + + if (empty($data)) { + return; + } + + /** @var Mysql $connection */ + $connection = $this->resourceConnection->getConnection(); + $connection->insertArray( + $this->resourceConnection->getTableName(self::TABLE_KEYWORD), + [self::KEYWORD], + $data, + AdapterInterface::INSERT_IGNORE + ); + + $this->saveAssetLinks->execute($assetId, $this->getKeywordIds($data)); + } + + /** + * Select keywords by names + * + * @param string[] $keywords + * @return int[] + */ + private function getKeywordIds(array $keywords): array + { + $connection = $this->resourceConnection->getConnection(); + $select = $connection->select() + ->from(['k' => $this->resourceConnection->getTableName(self::TABLE_KEYWORD)]) + ->columns(self::ID) + ->where('k.' . self::KEYWORD . ' in (?)', $keywords); + + return $connection->fetchCol($select); + } +} diff --git a/app/code/Magento/MediaGallery/Model/ResourceModel/SaveAssets.php b/app/code/Magento/MediaGallery/Model/ResourceModel/SaveAssets.php new file mode 100644 index 0000000000000..ec08addf93462 --- /dev/null +++ b/app/code/Magento/MediaGallery/Model/ResourceModel/SaveAssets.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Framework\Reflection\DataObjectProcessor; +use Magento\MediaGalleryApi\Api\Data\AssetInterface; +use Magento\MediaGalleryApi\Api\SaveAssetsInterface; +use Psr\Log\LoggerInterface; + +/** + * Save media asset to the database + */ +class SaveAssets implements SaveAssetsInterface +{ + private const TABLE_MEDIA_GALLERY_ASSET = 'media_gallery_asset'; + + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * Save constructor. + * + * @param ResourceConnection $resourceConnection + * @param LoggerInterface $logger + */ + public function __construct( + ResourceConnection $resourceConnection, + LoggerInterface $logger + ) { + $this->resourceConnection = $resourceConnection; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function execute(array $assets): void + { + $connection = $this->resourceConnection->getConnection(); + $tableName = $this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET); + + $failedAssets = []; + foreach ($assets as $asset) { + try { + $record = [ + 'id' => $asset->getId(), + 'path' => $asset->getPath(), + 'title' => $asset->getTitle(), + 'source' => $asset->getSource(), + 'content_type' => $asset->getContentType(), + 'width' => $asset->getWidth(), + 'height' => $asset->getHeight(), + 'size' => $asset->getSize(), + ]; + + if ($asset->getCreatedAt()) { + $record['created_at'] = $asset->getCreatedAt(); + } + + if ($asset->getUpdatedAt()) { + $record['updated_at'] = $asset->getUpdatedAt(); + } + + $connection->insertOnDuplicate($tableName, $record); + } catch (\Exception $exception) { + $this->logger->critical($exception); + $failedAssets[] = $asset; + } + } + + if (!empty($failedAssets)) { + throw new CouldNotSaveException( + __( + 'Could not save the media assets: %assets', + [ + 'assets' => implode(' ,', $failedAssets) + ] + ) + ); + } + } +} diff --git a/app/code/Magento/MediaGallery/Plugin/Wysiwyg/Images/Storage.php b/app/code/Magento/MediaGallery/Plugin/Wysiwyg/Images/Storage.php index 11331e4b9303f..11cb0f0dfd920 100644 --- a/app/code/Magento/MediaGallery/Plugin/Wysiwyg/Images/Storage.php +++ b/app/code/Magento/MediaGallery/Plugin/Wysiwyg/Images/Storage.php @@ -88,7 +88,7 @@ public function afterDeleteFile(StorageSubject $subject, StorageSubject $result, return $result; } - $relativePath = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getRelativePath($target); + $relativePath = $this->getMediaDirectoryRelativePath($target); if (!$relativePath) { return $result; } @@ -120,13 +120,22 @@ public function afterDeleteDirectory(StorageSubject $subject, $result, $path) } try { - $mediaDirectoryRead = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA); - $relativePath = $mediaDirectoryRead->getRelativePath($path); - $this->deleteMediaAssetByDirectoryPath->execute($relativePath); + $this->deleteMediaAssetByDirectoryPath->execute($this->getMediaDirectoryRelativePath($path)); } catch (ValidatorException $exception) { $this->logger->critical($exception); } return $result; } + + /** + * Get path relative to media directory + * + * @param string $path + * @return string + */ + private function getMediaDirectoryRelativePath(string $path): string + { + return $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getRelativePath($path); + } } diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionDuringMediaAssetInitializationTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionDuringMediaAssetInitializationTest.php index 49a5421e623a5..834e8027584dc 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionDuringMediaAssetInitializationTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionDuringMediaAssetInitializationTest.php @@ -23,9 +23,19 @@ */ class GetByIdExceptionDuringMediaAssetInitializationTest extends \PHPUnit\Framework\TestCase { - private const MEDIA_ASSET_STUB_ID = 1; - - private const MEDIA_ASSET_DATA = ['id' => 1]; + private const MEDIA_ASSET_STUB_ID = 45; + private const MEDIA_ASSET_DATA = [ + 'id' => 45, + 'path' => 'img.jpg', + 'title' => 'Img', + 'source' => 'Adobe Stock', + 'content_type' => 'image/jpeg', + 'width' => 420, + 'height' => 240, + 'size' => 12877, + 'created_at' => '2020', + 'updated_at' => '2020' + ]; /** * @var GetById|MockObject @@ -47,11 +57,6 @@ class GetByIdExceptionDuringMediaAssetInitializationTest extends \PHPUnit\Framew */ private $selectStub; - /** - * @var Statement|MockObject - */ - private $statementMock; - /** * @var LoggerInterface|MockObject */ @@ -81,8 +86,6 @@ protected function setUp(): void $this->selectStub->method('from')->willReturnSelf(); $this->selectStub->method('where')->willReturnSelf(); $this->adapter->method('select')->willReturn($this->selectStub); - - $this->statementMock = $this->getMockBuilder(\Zend_Db_Statement_Interface::class)->getMock(); } /** @@ -90,10 +93,14 @@ protected function setUp(): void */ public function testErrorDuringMediaAssetInitializationException(): void { - $this->statementMock->method('fetch')->willReturn(self::MEDIA_ASSET_DATA); - $this->adapter->method('query')->willReturn($this->statementMock); - - $this->assetFactory->expects($this->once())->method('create')->willThrowException(new \Exception()); + $statementMock = $this->createMock(\Zend_Db_Statement_Interface::class); + $statementMock->method('fetch') + ->willReturn(self::MEDIA_ASSET_DATA); + $this->adapter->method('query')->willReturn($statementMock); + + $this->assetFactory->expects($this->once()) + ->method('create') + ->willThrowException(new \Exception()); $this->expectException(IntegrationException::class); $this->logger->expects($this->any()) diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionOnGetDataTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionOnGetDataTest.php index f76552487e0f7..19c295424cbf9 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionOnGetDataTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdExceptionOnGetDataTest.php @@ -23,9 +23,19 @@ */ class GetByIdExceptionOnGetDataTest extends \PHPUnit\Framework\TestCase { - private const MEDIA_ASSET_STUB_ID = 1; - - private const MEDIA_ASSET_DATA = ['id' => 1]; + private const MEDIA_ASSET_STUB_ID = 45; + private const MEDIA_ASSET_DATA = [ + 'id' => 45, + 'path' => 'img.jpg', + 'title' => 'Img', + 'source' => 'Adobe Stock', + 'content_type' => 'image/jpeg', + 'width' => 420, + 'height' => 240, + 'size' => 12877, + 'created_at' => '2020', + 'updated_at' => '2020' + ]; /** * @var GetById|MockObject diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdSuccessfulTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdSuccessfulTest.php index c9e8416c53156..410dd5bef18c8 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdSuccessfulTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/GetByIdSuccessfulTest.php @@ -23,9 +23,19 @@ */ class GetByIdSuccessfulTest extends \PHPUnit\Framework\TestCase { - private const MEDIA_ASSET_STUB_ID = 1; - - private const MEDIA_ASSET_DATA = ['id' => 1]; + private const MEDIA_ASSET_STUB_ID = 45; + private const MEDIA_ASSET_DATA = [ + 'id' => 45, + 'path' => 'img.jpg', + 'title' => 'Img', + 'source' => 'Adobe Stock', + 'content_type' => 'image/jpeg', + 'width' => 420, + 'height' => 240, + 'size' => 12877, + 'created_at' => '2020', + 'updated_at' => '2020' + ]; /** * @var GetById|MockObject diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/SaveTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/SaveTest.php index 2f736fb832eac..6f82d2f2a5cb3 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/SaveTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Asset/Command/SaveTest.php @@ -9,7 +9,6 @@ use Magento\MediaGallery\Model\Asset\Command\Save; use Magento\MediaGalleryApi\Api\Data\AssetInterface; -use Magento\MediaGalleryApi\Model\DataExtractorInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Adapter\Pdo\Mysql; @@ -17,6 +16,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Magento\Framework\Reflection\DataObjectProcessor; use Psr\Log\LoggerInterface; /** @@ -24,7 +24,6 @@ */ class SaveTest extends TestCase { - /** * Constant for tablename of media gallery assets */ @@ -49,12 +48,14 @@ class SaveTest extends TestCase * Constant for image data */ private const IMAGE_DATA = [ + 'id' => null, 'path' => '/test/path', 'title' => 'Test Title', 'source' => 'Adobe Stock', 'content_type' => 'image/jpeg', 'height' => 4863, - 'width' => 12129 + 'width' => 12129, + 'size' => 300, ]; /** @@ -63,14 +64,14 @@ class SaveTest extends TestCase private $resourceConnectionMock; /** - * @var MockObject | DataExtractorInterface + * @var MockObject | LoggerInterface */ private $loggerMock; /** - * @var MockObject | LoggerInterface + * @var MockObject | DataObjectProcessor */ - private $extractorMock; + private $objectProcessor; /** * @var MockObject | AdapterInterface @@ -97,7 +98,7 @@ protected function setUp(): void $this->mediaAssetMock = $this->createMock(AssetInterface::class); /* Save constructor mocks */ - $this->extractorMock = $this->createMock(DataExtractorInterface::class); + $this->objectProcessor = $this->createMock(DataObjectProcessor::class); $this->loggerMock = $this->createMock(LoggerInterface::class); $this->resourceConnectionMock = $this->createConfiguredMock( ResourceConnection::class, @@ -112,7 +113,7 @@ protected function setUp(): void Save::class, [ 'resourceConnection' => $this->resourceConnectionMock, - 'extractor' => $this->extractorMock, + 'objectProcessor' => $this->objectProcessor, 'logger' => $this->loggerMock ] ); @@ -126,11 +127,16 @@ public function testSuccessfulExecute(): void $this->resourceConnectionMock->expects(self::once())->method('getConnection'); $this->resourceConnectionMock->expects(self::once())->method('getTableName'); - $this->extractorMock - ->expects(self::once()) - ->method('extract') - ->with($this->mediaAssetMock, AssetInterface::class) - ->willReturn(self::IMAGE_DATA); + $this->mediaAssetMock->expects(self::once())->method('getId')->willReturn(self::IMAGE_DATA['id']); + $this->mediaAssetMock->expects(self::once())->method('getPath')->willReturn(self::IMAGE_DATA['path']); + $this->mediaAssetMock->expects(self::once())->method('getTitle')->willReturn(self::IMAGE_DATA['title']); + $this->mediaAssetMock->expects(self::once())->method('getSource')->willReturn(self::IMAGE_DATA['source']); + $this->mediaAssetMock->expects(self::once())->method('getWidth')->willReturn(self::IMAGE_DATA['width']); + $this->mediaAssetMock->expects(self::once())->method('getHeight')->willReturn(self::IMAGE_DATA['height']); + $this->mediaAssetMock->expects(self::once())->method('getSize')->willReturn(self::IMAGE_DATA['size']); + $this->mediaAssetMock->expects(self::once()) + ->method('getContentType') + ->willReturn(self::IMAGE_DATA['content_type']); $this->adapterMock ->expects(self::once()) @@ -155,11 +161,16 @@ public function testExceptionExecute(): void $this->resourceConnectionMock->expects(self::once())->method('getConnection'); $this->resourceConnectionMock->expects(self::once())->method('getTableName'); - $this->extractorMock - ->expects(self::once()) - ->method('extract') - ->with($this->mediaAssetMock, AssetInterface::class) - ->willReturn(self::IMAGE_DATA); + $this->mediaAssetMock->expects(self::once())->method('getId')->willReturn(self::IMAGE_DATA['id']); + $this->mediaAssetMock->expects(self::once())->method('getPath')->willReturn(self::IMAGE_DATA['path']); + $this->mediaAssetMock->expects(self::once())->method('getTitle')->willReturn(self::IMAGE_DATA['title']); + $this->mediaAssetMock->expects(self::once())->method('getSource')->willReturn(self::IMAGE_DATA['source']); + $this->mediaAssetMock->expects(self::once())->method('getWidth')->willReturn(self::IMAGE_DATA['width']); + $this->mediaAssetMock->expects(self::once())->method('getHeight')->willReturn(self::IMAGE_DATA['height']); + $this->mediaAssetMock->expects(self::once())->method('getSize')->willReturn(self::IMAGE_DATA['size']); + $this->mediaAssetMock->expects(self::once()) + ->method('getContentType') + ->willReturn(self::IMAGE_DATA['content_type']); $this->adapterMock ->expects(self::once()) diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/DataExtractorTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/DataExtractorTest.php deleted file mode 100644 index f70e4ccdae22c..0000000000000 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/DataExtractorTest.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\MediaGallery\Test\Unit\Model; - -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\MediaGallery\Model\Asset; -use Magento\MediaGallery\Model\DataExtractor; -use Magento\MediaGallery\Model\Keyword; -use Magento\MediaGalleryApi\Api\Data\AssetInterface; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; - -class DataExtractorTest extends TestCase -{ - /** - * @var DataExtractor|MockObject - */ - private $dataExtractor; - - /** - * Initialize basic test class mocks - */ - protected function setUp(): void - { - $this->dataExtractor = new DataExtractor(); - } - - /** - * Test extract object data by interface - * - * @dataProvider assetProvider - * - * @param string $class - * @param string|null $interfaceClass - * @param array $expectedData - * - * @throws \ReflectionException - */ - public function testExtractData(string $class, $interfaceClass, array $expectedData): void - { - $data = []; - foreach ($expectedData as $expectedDataKey => $expectedDataItem) { - $data[$expectedDataKey] = $expectedDataItem['value']; - } - $model = (new ObjectManager($this))->getObject( - $class, - [ - 'data' => $data, - ] - ); - if ($interfaceClass) { - $receivedData = $this->dataExtractor->extract($model, $interfaceClass); - $this->checkAssetValues($expectedData, $receivedData, $model); - } else { - $receivedData = $this->dataExtractor->extract($model); - $this->checkKeyWordValues($expectedData, $receivedData, $model); - } - } - - /** - * @param array $expectedData - * @param array $data - * @param object $model - */ - private function checkAssetValues(array $expectedData, array $data, $model) - { - foreach ($expectedData as $expectedDataKey => $expectedDataItem) { - $this->assertEquals($data[$expectedDataKey] ?? null, $model->{$expectedDataItem['method']}()); - $this->assertEquals($data[$expectedDataKey] ?? null, $expectedDataItem['value']); - } - $this->assertEquals(array_keys($expectedData), array_keys($data)); - } - - /** - * @param array $expectedData - * @param array $data - * @param object $model - */ - private function checkKeyWordValues(array $expectedData, array $data, $model) - { - foreach ($expectedData as $expectedDataKey => $expectedDataItem) { - $this->assertEquals($data[$expectedDataKey] ?? null, $model->{$expectedDataItem['method']}()); - $this->assertEquals($data[$expectedDataKey] ?? null, $expectedDataItem['value']); - } - $this->assertEquals(array_keys($expectedData), array_keys(array_slice($data, 0, 2))); - } - - /** - * @return array - */ - public function assetProvider() - { - return [ - 'Asset conversion with interface' => [ - Asset::class, - AssetInterface::class, - [ - 'id' => [ - 'value' => 2, - 'method' => 'getId', - ], - 'path' => [ - 'value' => 'path', - 'method' => 'getPath', - ], - 'title' => [ - 'value' => 'title', - 'method' => 'getTitle', - ], - 'source' => [ - 'value' => 'source', - 'method' => 'getSource', - ], - 'content_type' => [ - 'value' => 'content_type', - 'method' => 'getContentType', - ], - 'height' => [ - 'value' => 4, - 'method' => 'getHeight', - ], - 'width' => [ - 'value' => 3, - 'method' => 'getWidth', - ], - 'size' => [ - 'value' => 300, - 'method' => 'getSize', - ], - 'created_at' => [ - 'value' => '2019-11-28 10:40:09', - 'method' => 'getCreatedAt', - ], - 'updated_at' => [ - 'value' => '2019-11-28 10:41:08', - 'method' => 'getUpdatedAt', - ], - ], - ], - 'Keyword conversion without interface' => [ - Keyword::class, - '', - [ - 'id' => [ - 'value' => 2, - 'method' => 'getId', - ], - 'keyword' => [ - 'value' => 'keyword', - 'method' => 'getKeyword', - ], - ], - ] - ]; - } -} diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Directory/IsBlacklistedTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Directory/IsBlacklistedTest.php new file mode 100644 index 0000000000000..5b069dcc70030 --- /dev/null +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Directory/IsBlacklistedTest.php @@ -0,0 +1,72 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Test\Unit\Model\Directory; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\MediaGallery\Model\Directory\IsBlacklisted; +use Magento\MediaGalleryApi\Model\BlacklistPatternsConfigInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * Test for IsBlacklisted + */ +class IsBlacklistedTest extends TestCase +{ + /** + * @var IsBlacklisted + */ + private $object; + + /** + * @var BlacklistPatternsConfigInterface|MockObject + */ + private $config; + + /** + * Initialize basic test class mocks + */ + protected function setUp(): void + { + $this->config = $this->getMockBuilder(BlacklistPatternsConfigInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->config->expects($this->at(0))->method('get')->willReturn([ + 'tmp' => '/pub\/media\/tmp/', + 'captcha' => '/pub\/media\/captcha/' + ]); + $this->object = (new ObjectManager($this))->getObject(IsBlacklisted::class, [ + 'config' => $this->config + ]); + } + + /** + * Test if the directory path is blacklisted + * + * @param string $path + * @param bool $isExcluded + * @dataProvider pathsProvider + */ + public function testExecute(string $path, bool $isExcluded): void + { + $this->assertEquals($isExcluded, $this->object->execute($path)); + } + + /** + * Data provider for testIsExcluded + * + * @return array + */ + public function pathsProvider() + { + return [ + ['/var/www/html/pub/media/tmp/somedir', true], + ['/var/www/html/pub/media/wysiwyg/somedir', false] + ]; + } +} diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/GetAssetKeywordsTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/GetAssetKeywordsTest.php index 2ccac4eac8343..930068aebb3fe 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/GetAssetKeywordsTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/GetAssetKeywordsTest.php @@ -19,7 +19,7 @@ use Psr\Log\LoggerInterface; /** - * GetAssetKeywordsTest + * Test for GetAssetKeywords */ class GetAssetKeywordsTest extends TestCase { @@ -83,9 +83,32 @@ public function testFind(array $databaseQueryResult, int $expectedNumberOfFoundK public function casesProvider(): array { return [ - 'not_found' => [[],0], - 'find_one_keyword' => [['keywordRawData'],1], - 'find_several_keywords' => [['keywordRawData', 'keywordRawData'],2], + 'not_found' => [ + [], + 0 + ], + 'find_one_keyword' => [ + [ + [ + 'id' => 1, + 'keyword' => 'keywordRawData' + ] + ], + 1 + ], + 'find_several_keywords' => [ + [ + [ + 'id' => 1, + 'keyword' => 'keywordRawData' + ], + [ + 'id' => 2, + 'keyword' => 'keywordRawData2' + ] + ], + 2 + ], ]; } diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetKeywordsTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetKeywordsTest.php index a55c60024c08d..302c8c8774bc6 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetKeywordsTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetKeywordsTest.php @@ -13,13 +13,13 @@ use Magento\Framework\DB\Select; use Magento\Framework\Exception\CouldNotSaveException; use Magento\MediaGallery\Model\Keyword\Command\SaveAssetKeywords; -use Magento\MediaGallery\Model\Keyword\Command\SaveAssetLinks; +use Magento\MediaGallery\Model\ResourceModel\Keyword\SaveAssetLinks; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; /** - * SaveAssetKeywordsTest. + * Test for SaveAssetKeywords */ class SaveAssetKeywordsTest extends TestCase { diff --git a/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetLinksTest.php b/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetLinksTest.php index 2981c534586e2..fe9202353fa2e 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetLinksTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Model/Keyword/Command/SaveAssetLinksTest.php @@ -7,16 +7,16 @@ namespace Magento\MediaGallery\Test\Unit\Model\Keyword\Command; -use Magento\MediaGallery\Model\Keyword\Command\SaveAssetLinks; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\Exception\CouldNotSaveException; +use Magento\MediaGallery\Model\ResourceModel\Keyword\SaveAssetLinks; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; /** - * SaveAssetLinksTest. + * Test for SaveAssetLinks */ class SaveAssetLinksTest extends TestCase { diff --git a/app/code/Magento/MediaGallery/Test/Unit/Plugin/Images/StorageTest.php b/app/code/Magento/MediaGallery/Test/Unit/Plugin/Images/StorageTest.php index 4ac448733c47f..817c56b34e348 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Plugin/Images/StorageTest.php +++ b/app/code/Magento/MediaGallery/Test/Unit/Plugin/Images/StorageTest.php @@ -22,12 +22,11 @@ use Psr\Log\LoggerInterface; /** - * Test the DeleteByDirectoryPath command model + * Test for the Sorage::deleteDirectory after plugin */ class StorageTest extends TestCase { private const NON_STRING_PATH = 2020; - private const NON_EXISTENT_PATH = 'non_existent'; private const INVALID_PATH = '&&'; private const VALID_PATH = 'test-directory-path/'; diff --git a/app/code/Magento/MediaGallery/composer.json b/app/code/Magento/MediaGallery/composer.json index 977277d993061..686cec00b7f55 100644 --- a/app/code/Magento/MediaGallery/composer.json +++ b/app/code/Magento/MediaGallery/composer.json @@ -5,8 +5,7 @@ "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", "magento/module-media-gallery-api": "*", - "magento/module-cms": "*", - "magento/module-catalog": "*" + "magento/module-cms": "*" }, "type": "magento2-module", "license": [ diff --git a/app/code/Magento/MediaGallery/etc/db_schema.xml b/app/code/Magento/MediaGallery/etc/db_schema.xml index 8bcad28de2a8e..13e619dd9e74a 100644 --- a/app/code/Magento/MediaGallery/etc/db_schema.xml +++ b/app/code/Magento/MediaGallery/etc/db_schema.xml @@ -26,6 +26,9 @@ <constraint xsi:type="unique" referenceId="MEDIA_GALLERY_ID_PATH_TITLE_CONTENT_TYPE_WIDTH_HEIGHT"> <column name="path"/> </constraint> + <index referenceId="MEDIA_GALLERY_ASSET_TITLE" indexType="fulltext"> + <column name="title"/> + </index> </table> <table name="media_gallery_keyword" resource="default" engine="innodb" comment="Media Gallery Keyword"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Keyword ID"/> diff --git a/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json b/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json index 9e187e6dea4a5..8f5098caa9753 100644 --- a/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json +++ b/app/code/Magento/MediaGallery/etc/db_schema_whitelist.json @@ -14,7 +14,8 @@ }, "index": { "MEDIA_GALLERY_ID": true, - "MEDIA_GALLERY_ASSET_ID": true + "MEDIA_GALLERY_ASSET_ID": true, + "MEDIA_GALLERY_ASSET_TITLE": true }, "constraint": { "MEDIA_GALLERY_ID_PATH_TITLE_CONTENT_TYPE_WIDTH_HEIGHT": true, diff --git a/app/code/Magento/MediaGallery/etc/di.xml b/app/code/Magento/MediaGallery/etc/di.xml index 24ed42b2b06dd..a85c26e275226 100644 --- a/app/code/Magento/MediaGallery/etc/di.xml +++ b/app/code/Magento/MediaGallery/etc/di.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\MediaGalleryApi\Api\Data\KeywordInterface" type="Magento\MediaGallery\Model\Keyword"/> <preference for="Magento\MediaGalleryApi\Api\Data\AssetInterface" type="Magento\MediaGallery\Model\Asset"/> - + <preference for="Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface" type="Magento\MediaGallery\Model\AssetKeywords"/> <preference for="Magento\MediaGalleryApi\Model\Asset\Command\GetByIdInterface" type="Magento\MediaGallery\Model\Asset\Command\GetById"/> <preference for="Magento\MediaGalleryApi\Model\Asset\Command\SaveInterface" type="Magento\MediaGallery\Model\Asset\Command\Save"/> <preference for="Magento\MediaGalleryApi\Model\Asset\Command\GetByPathInterface" type="Magento\MediaGallery\Model\Asset\Command\GetByPath"/> @@ -17,16 +17,44 @@ <preference for="Magento\MediaGalleryApi\Model\Keyword\Command\GetAssetKeywordsInterface" type="Magento\MediaGallery\Model\Keyword\Command\GetAssetKeywords"/> <preference for="Magento\MediaGalleryApi\Model\Keyword\Command\SaveAssetKeywordsInterface" type="Magento\MediaGallery\Model\Keyword\Command\SaveAssetKeywords"/> - <preference for="Magento\MediaGalleryApi\Model\Keyword\Command\SaveAssetLinksInterface" type="Magento\MediaGallery\Model\Keyword\Command\SaveAssetLinks"/> - <preference for="Magento\MediaGalleryApi\Model\DataExtractorInterface" type="Magento\MediaGallery\Model\DataExtractor"/> + <preference for="Magento\MediaGalleryApi\Api\CreateDirectoriesByPathsInterface" type="Magento\MediaGallery\Model\Directory\Command\CreateByPaths"/> + <preference for="Magento\MediaGalleryApi\Api\DeleteDirectoriesByPathsInterface" type="Magento\MediaGallery\Model\Directory\Command\DeleteByPaths"/> + + <preference for="Magento\MediaGalleryApi\Api\IsPathBlacklistedInterface" type="Magento\MediaGallery\Model\Directory\IsBlacklisted"/> + + <preference for="Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface" type="Magento\MediaGallery\Model\ResourceModel\DeleteAssetsByPaths"/> + <preference for="Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface" type="Magento\MediaGallery\Model\ResourceModel\GetAssetsByIds"/> + <preference for="Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface" type="Magento\MediaGallery\Model\ResourceModel\GetAssetsByPaths"/> + <preference for="Magento\MediaGalleryApi\Api\SaveAssetsInterface" type="Magento\MediaGallery\Model\ResourceModel\SaveAssets"/> + <preference for="Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface" type="Magento\MediaGallery\Model\ResourceModel\Keyword\GetAssetsKeywords"/> + <preference for="Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface" type="Magento\MediaGallery\Model\ResourceModel\Keyword\SaveAssetsKeywords"/> - <type name="Magento\Catalog\Model\Product\Gallery\Processor"> - <plugin name="media_gallery_image_remove_metadata" type="Magento\MediaGallery\Plugin\Product\Gallery\Processor" - sortOrder="10" disabled="false"/> - </type> <type name="Magento\Cms\Model\Wysiwyg\Images\Storage"> <plugin name="media_gallery_image_remove_metadata_after_wysiwyg" type="Magento\MediaGallery\Plugin\Wysiwyg\Images\Storage" sortOrder="10" disabled="false"/> </type> + <virtualType name="Magento\MediaGallery\Model\Directory\Config\Reader" type="Magento\Framework\Config\Reader\Filesystem"> + <arguments> + <argument name="fileName" xsi:type="string">directory.xml</argument> + <argument name="converter" xsi:type="object">Magento\MediaGallery\Model\Directory\Config\Converter</argument> + <argument name="schemaLocator" xsi:type="object">Magento\MediaGallery\Model\Directory\Config\SchemaLocator</argument> + <argument name="idAttributes" xsi:type="array"> + <item name="/config/blacklist/patterns/pattern" xsi:type="string">name</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\MediaGallery\Model\Directory\Config\Data" type="Magento\Framework\Config\Data"> + <arguments> + <argument name="reader" xsi:type="object">Magento\MediaGallery\Model\Directory\Config\Reader</argument> + <argument name="cacheId" xsi:type="string">Media_Gallery_Patterns_CacheId</argument> + </arguments> + </virtualType> + <type name="Magento\MediaGallery\Model\Directory\BlacklistPatternsConfig"> + <arguments> + <argument name="data" xsi:type="object">Magento\MediaGallery\Model\Directory\Config\Data</argument> + </arguments> + </type> + + <preference for="Magento\MediaGalleryApi\Model\BlacklistPatternsConfigInterface" type="Magento\MediaGallery\Model\Directory\BlacklistPatternsConfig"/> </config> diff --git a/app/code/Magento/MediaGallery/etc/directory.xml b/app/code/Magento/MediaGallery/etc/directory.xml new file mode 100644 index 0000000000000..92f50b2dd0a30 --- /dev/null +++ b/app/code/Magento/MediaGallery/etc/directory.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_MediaGalleryApi:etc/directory.xsd"> + <blacklist> + <patterns> + <pattern name="captcha">/^captcha/</pattern> + <pattern name="customer">/^customer/</pattern> + <pattern name="downloadable">/^downloadable/</pattern> + <pattern name="import">/^import/</pattern> + <pattern name="theme">/^theme/</pattern> + <pattern name="theme_customization">/^theme_customization/</pattern> + <pattern name="tmp">/^tmp/</pattern> + <pattern name="directories-with-dots">/^\./</pattern> + </patterns> + </blacklist> +</config> diff --git a/app/code/Magento/MediaGalleryApi/Api/CreateDirectoriesByPathsInterface.php b/app/code/Magento/MediaGalleryApi/Api/CreateDirectoriesByPathsInterface.php new file mode 100644 index 0000000000000..a0a1ec891237f --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/CreateDirectoriesByPathsInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Create folders by provided paths + * @api + */ +interface CreateDirectoriesByPathsInterface +{ + /** + * Create new directories by provided paths + * + * @param string[] $paths + * @return void + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function execute(array $paths): void; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php b/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php index 0f4b78a6dc603..5df420a274933 100644 --- a/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php +++ b/app/code/Magento/MediaGalleryApi/Api/Data/AssetInterface.php @@ -13,6 +13,7 @@ /** * Represents a media gallery asset which contains information about a media asset entity such * as path to the media storage, media asset title and its content type, etc. + * @api */ interface AssetInterface extends ExtensibleDataInterface { @@ -38,7 +39,7 @@ public function getPath(): string; public function getTitle(): ?string; /** - * Get source of the file + * Get the name of the channel/stock/integration file was retrieved from. null if not identified. * * @return string|null */ @@ -75,29 +76,29 @@ public function getSize(): int; /** * Get created at * - * @return string + * @return string|null */ - public function getCreatedAt(): string; + public function getCreatedAt(): ?string; /** * Get updated at * - * @return string + * @return string|null */ - public function getUpdatedAt(): string; + public function getUpdatedAt(): ?string; /** * Retrieve existing extension attributes object or create a new one. * * @return \Magento\MediaGalleryApi\Api\Data\AssetExtensionInterface|null */ - public function getExtensionAttributes(): AssetExtensionInterface; + public function getExtensionAttributes(): ?AssetExtensionInterface; /** * Set extension attributes * - * @param \Magento\MediaGalleryApi\Api\Data\AssetExtensionInterface $extensionAttributes + * @param \Magento\MediaGalleryApi\Api\Data\AssetExtensionInterface|null $extensionAttributes * @return void */ - public function setExtensionAttributes(AssetExtensionInterface $extensionAttributes): void; + public function setExtensionAttributes(?AssetExtensionInterface $extensionAttributes): void; } diff --git a/app/code/Magento/MediaGalleryApi/Api/Data/AssetKeywordsInterface.php b/app/code/Magento/MediaGalleryApi/Api/Data/AssetKeywordsInterface.php new file mode 100644 index 0000000000000..1c18225470493 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/Data/AssetKeywordsInterface.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api\Data; + +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsExtensionInterface; +use Magento\Framework\Api\ExtensibleDataInterface; + +/** + * Interface for asset's keywords aggregation + * @api + */ +interface AssetKeywordsInterface extends ExtensibleDataInterface +{ + /** + * Get ID + * + * @return int + */ + public function getAssetId(): int; + + /** + * Get the keyword + * + * @return KeywordInterface[] + */ + public function getKeywords(): array; + + /** + * Get extension attributes + * + * @return \Magento\MediaGalleryApi\Api\Data\AssetKeywordsExtensionInterface|null + */ + public function getExtensionAttributes(): ?AssetKeywordsExtensionInterface; + + /** + * Set extension attributes + * + * @param \Magento\MediaGalleryApi\Api\Data\AssetKeywordsExtensionInterface|null $extensionAttributes + * @return void + */ + public function setExtensionAttributes(?AssetKeywordsExtensionInterface $extensionAttributes): void; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/Data/KeywordInterface.php b/app/code/Magento/MediaGalleryApi/Api/Data/KeywordInterface.php index ae3b7dbd76291..3cba118e03a1a 100644 --- a/app/code/Magento/MediaGalleryApi/Api/Data/KeywordInterface.php +++ b/app/code/Magento/MediaGalleryApi/Api/Data/KeywordInterface.php @@ -12,6 +12,7 @@ /** * Represents a media gallery keyword. This object contains information about a media asset keyword entity. + * @api */ interface KeywordInterface extends ExtensibleDataInterface { @@ -34,13 +35,13 @@ public function getKeyword(): string; * * @return \Magento\MediaGalleryApi\Api\Data\KeywordExtensionInterface|null */ - public function getExtensionAttributes(): KeywordExtensionInterface; + public function getExtensionAttributes(): ?KeywordExtensionInterface; /** * Set extension attributes * - * @param \Magento\MediaGalleryApi\Api\Data\KeywordExtensionInterface $extensionAttributes + * @param \Magento\MediaGalleryApi\Api\Data\KeywordExtensionInterface|null $extensionAttributes * @return void */ - public function setExtensionAttributes(KeywordExtensionInterface $extensionAttributes): void; + public function setExtensionAttributes(?KeywordExtensionInterface $extensionAttributes): void; } diff --git a/app/code/Magento/MediaGalleryApi/Api/DeleteAssetsByPathsInterface.php b/app/code/Magento/MediaGalleryApi/Api/DeleteAssetsByPathsInterface.php new file mode 100644 index 0000000000000..5370235a31b95 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/DeleteAssetsByPathsInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Delete media assets by exact or directory paths + * @api + */ +interface DeleteAssetsByPathsInterface +{ + /** + * Delete media assets by paths. Removes all the assets which paths start with provided paths + * + * @param string[] $paths + * @return void + */ + public function execute(array $paths): void; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/DeleteDirectoriesByPathsInterface.php b/app/code/Magento/MediaGalleryApi/Api/DeleteDirectoriesByPathsInterface.php new file mode 100644 index 0000000000000..fe3be88fa0073 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/DeleteDirectoriesByPathsInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Delete folders by provided paths + * @api + */ +interface DeleteDirectoriesByPathsInterface +{ + /** + * Deletes the existing folders + * + * @param string[] $paths + * @return void + * @throws \Magento\Framework\Exception\CouldNotDeleteException + */ + public function execute(array $paths): void; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/GetAssetsByIdsInterface.php b/app/code/Magento/MediaGalleryApi/Api/GetAssetsByIdsInterface.php new file mode 100644 index 0000000000000..5df6722a190d4 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/GetAssetsByIdsInterface.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Get media gallery assets by id attribute + * @api + */ +interface GetAssetsByIdsInterface +{ + /** + * Get media asset by id + * + * @param int[] $ids + * @return \Magento\MediaGalleryApi\Api\Data\AssetInterface[] + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function execute(array $ids): array; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/GetAssetsByPathsInterface.php b/app/code/Magento/MediaGalleryApi/Api/GetAssetsByPathsInterface.php new file mode 100644 index 0000000000000..dbaed6e0e9123 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/GetAssetsByPathsInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Get media gallery assets by paths in media storage + * @api + */ +interface GetAssetsByPathsInterface +{ + /** + * Get media asset list + * + * @param string[] $paths + * @return \Magento\MediaGalleryApi\Api\Data\AssetInterface[] + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function execute(array $paths): array; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/GetAssetsKeywordsInterface.php b/app/code/Magento/MediaGalleryApi/Api/GetAssetsKeywordsInterface.php new file mode 100644 index 0000000000000..99b05291f32a0 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/GetAssetsKeywordsInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Get a media gallery asset keywords related to media gallery asset ids provided + * @api + */ +interface GetAssetsKeywordsInterface +{ + /** + * Get assets related keywords + * + * @param int[] $assetIds + * @return \Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface[] + */ + public function execute(array $assetIds): array; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/IsPathBlacklistedInterface.php b/app/code/Magento/MediaGalleryApi/Api/IsPathBlacklistedInterface.php new file mode 100644 index 0000000000000..cbd23ec3fbde7 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/IsPathBlacklistedInterface.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Check if the path is blacklisted for media gallery. + * + * Directory path may be blacklisted if it's reserved by the system. + * @api + */ +interface IsPathBlacklistedInterface +{ + /** + * Check if the path is excluded from displaying and processing in the media gallery + * + * @param string $path + * @return bool + */ + public function execute(string $path): bool; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/SaveAssetsInterface.php b/app/code/Magento/MediaGalleryApi/Api/SaveAssetsInterface.php new file mode 100644 index 0000000000000..c63f7bd8c0818 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/SaveAssetsInterface.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Save media gallery assets to the database + * @api + */ +interface SaveAssetsInterface +{ + /** + * Save media asset. The saved asset can later be retrieved by path + * + * @param \Magento\MediaGalleryApi\Api\Data\AssetInterface[] $assets + * @return void + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function execute(array $assets): void; +} diff --git a/app/code/Magento/MediaGalleryApi/Api/SaveAssetsKeywordsInterface.php b/app/code/Magento/MediaGalleryApi/Api/SaveAssetsKeywordsInterface.php new file mode 100644 index 0000000000000..04efe7d32ccc1 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Api/SaveAssetsKeywordsInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGalleryApi\Api; + +/** + * Save keywords related to assets to the database + * @api + */ +interface SaveAssetsKeywordsInterface +{ + /** + * Save assets keywords + * + * @param \Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface[] $assetKeywords + * @return void + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function execute(array $assetKeywords): void; +} diff --git a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByDirectoryPathInterface.php b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByDirectoryPathInterface.php index e55f7cb714f77..79b209823aeb0 100644 --- a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByDirectoryPathInterface.php +++ b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByDirectoryPathInterface.php @@ -11,6 +11,8 @@ /** * A command represents the media gallery assets delete action. A media gallery asset is filtered by directory * path value. + * @deprecated use \Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface instead + * @see \Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface */ interface DeleteByDirectoryPathInterface { @@ -18,7 +20,6 @@ interface DeleteByDirectoryPathInterface * Delete media assets by directory path * * @param string $directoryPath - * * @return void */ public function execute(string $directoryPath): void; diff --git a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByPathInterface.php b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByPathInterface.php index b3612a67ed536..f33022e75d2fe 100644 --- a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByPathInterface.php +++ b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/DeleteByPathInterface.php @@ -10,6 +10,8 @@ /** * A command represents the media gallery asset delete action. A media gallery asset is filtered by path value. + * @deprecated use \Magento\MediaGalleryApi\Api\DeleteAssetsByPathInterface instead + * @see \Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface */ interface DeleteByPathInterface { @@ -17,7 +19,6 @@ interface DeleteByPathInterface * Delete media asset by path * * @param string $mediaAssetPath - * * @return void */ public function execute(string $mediaAssetPath): void; diff --git a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByIdInterface.php b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByIdInterface.php index ef2ceb5ffbfe6..65cc2e3eae109 100644 --- a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByIdInterface.php +++ b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByIdInterface.php @@ -10,6 +10,8 @@ /** * A command represents the get media gallery asset by using media gallery asset id as a filter parameter. + * @deprecated use \Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface instead + * @see \Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface */ interface GetByIdInterface { @@ -17,7 +19,6 @@ interface GetByIdInterface * Get media asset by id * * @param int $mediaAssetId - * * @return \Magento\MediaGalleryApi\Api\Data\AssetInterface * @throws \Magento\Framework\Exception\NoSuchEntityException * @throws \Magento\Framework\Exception\IntegrationException diff --git a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByPathInterface.php b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByPathInterface.php index 547b0dc695dae..d8d5b6773fbbc 100644 --- a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByPathInterface.php +++ b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/GetByPathInterface.php @@ -10,15 +10,16 @@ /** * A command represents the get media gallery asset by using media gallery asset path as a filter parameter. + * @deprecated use \Magento\MediaGalleryApi\Api\GetAssetsByPathInterface instead + * @see \Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface */ interface GetByPathInterface { /** * Get media asset list * - * @param string $mediaFilePath - * + * @param string $path * @return \Magento\MediaGalleryApi\Api\Data\AssetInterface */ - public function execute(string $mediaFilePath): \Magento\MediaGalleryApi\Api\Data\AssetInterface; + public function execute(string $path): \Magento\MediaGalleryApi\Api\Data\AssetInterface; } diff --git a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/SaveInterface.php b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/SaveInterface.php index b3e3607e6e822..610ecf0cd22bf 100644 --- a/app/code/Magento/MediaGalleryApi/Model/Asset/Command/SaveInterface.php +++ b/app/code/Magento/MediaGalleryApi/Model/Asset/Command/SaveInterface.php @@ -12,14 +12,15 @@ /** * A command which executes the media gallery asset save operation. + * @deprecated use \Magento\MediaGalleryApi\Api\SaveAssetsInterface instead + * @see \Magento\MediaGalleryApi\Api\SaveAssetsInterface */ interface SaveInterface { /** - * Save media asset + * Save media asset and return the media asset id * * @param \Magento\MediaGalleryApi\Api\Data\AssetInterface $mediaAsset - * * @return int * @throws \Magento\Framework\Exception\CouldNotSaveException */ diff --git a/app/code/Magento/MediaGalleryApi/Model/BlacklistPatternsConfigInterface.php b/app/code/Magento/MediaGalleryApi/Model/BlacklistPatternsConfigInterface.php new file mode 100644 index 0000000000000..b4710f32e0c46 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/Model/BlacklistPatternsConfigInterface.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\MediaGalleryApi\Model; + +/** + * Returns list of blacklist regexp patterns + */ +interface BlacklistPatternsConfigInterface +{ + /** + * Get regexp patterns + * + * @return array + */ + public function get(): array; +} diff --git a/app/code/Magento/MediaGalleryApi/Model/DataExtractorInterface.php b/app/code/Magento/MediaGalleryApi/Model/DataExtractorInterface.php deleted file mode 100644 index 6570cd2235412..0000000000000 --- a/app/code/Magento/MediaGalleryApi/Model/DataExtractorInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\MediaGalleryApi\Model; - -/** - * Extract data from an object using available getters - */ -interface DataExtractorInterface -{ - /** - * Extract data from an object using available getters (does not process extension attributes) - * - * @param object $object - * @param string|null $interface - * @return array - */ - public function extract($object, string $interface = null): array; -} diff --git a/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/GetAssetKeywordsInterface.php b/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/GetAssetKeywordsInterface.php index d449df5684c4b..e42c370c1c6f7 100644 --- a/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/GetAssetKeywordsInterface.php +++ b/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/GetAssetKeywordsInterface.php @@ -9,6 +9,8 @@ /** * A command represents functionality to get a media gallery asset keywords filtered by media gallery asset id. + * @deprecated use \Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface instead + * @see \Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface */ interface GetAssetKeywordsInterface { @@ -16,7 +18,6 @@ interface GetAssetKeywordsInterface * Get asset related keywords. * * @param int $assetId - * * @return \Magento\MediaGalleryApi\Api\Data\KeywordInterface[] */ public function execute(int $assetId): array; diff --git a/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/SaveAssetKeywordsInterface.php b/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/SaveAssetKeywordsInterface.php index 9c0d89c3456f8..824cbca178988 100644 --- a/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/SaveAssetKeywordsInterface.php +++ b/app/code/Magento/MediaGalleryApi/Model/Keyword/Command/SaveAssetKeywordsInterface.php @@ -9,6 +9,8 @@ /** * A command represents the media gallery asset keywords save operation. + * @deprecated use \Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface instead + * @see \Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface */ interface SaveAssetKeywordsInterface { diff --git a/app/code/Magento/MediaGalleryApi/etc/directory.xsd b/app/code/Magento/MediaGalleryApi/etc/directory.xsd new file mode 100644 index 0000000000000..2ad76c8fcc9f2 --- /dev/null +++ b/app/code/Magento/MediaGalleryApi/etc/directory.xsd @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="config" type="configType"> + </xs:element> + + <xs:complexType name="configType"> + <xs:sequence> + <xs:element type="blacklistType" name="blacklist" maxOccurs="unbounded" minOccurs="1"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="blacklistType"> + <xs:annotation> + <xs:documentation> + Blacklist used for excluding directories from media gallery rendering and operations + </xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element type="patternsType" name="patterns" maxOccurs="unbounded" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="patternsType"> + <xs:annotation> + <xs:documentation> + List of directory paths RegExp patterns + </xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element type="patternType" name="pattern" maxOccurs="unbounded" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="patternType"> + <xs:annotation> + <xs:documentation> + Directory path regexp pattern + </xs:documentation> + </xs:annotation> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute type="xs:string" name="name" use="required"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> +</xs:schema> diff --git a/app/code/Magento/AuthorizenetCardinal/LICENSE.txt b/app/code/Magento/MediaGalleryCatalog/LICENSE.txt similarity index 100% rename from app/code/Magento/AuthorizenetCardinal/LICENSE.txt rename to app/code/Magento/MediaGalleryCatalog/LICENSE.txt diff --git a/app/code/Magento/AuthorizenetCardinal/LICENSE_AFL.txt b/app/code/Magento/MediaGalleryCatalog/LICENSE_AFL.txt similarity index 100% rename from app/code/Magento/AuthorizenetCardinal/LICENSE_AFL.txt rename to app/code/Magento/MediaGalleryCatalog/LICENSE_AFL.txt diff --git a/app/code/Magento/MediaGallery/Plugin/Product/Gallery/Processor.php b/app/code/Magento/MediaGalleryCatalog/Plugin/Product/Gallery/RemoveAssetAfterRemoveImage.php similarity index 69% rename from app/code/Magento/MediaGallery/Plugin/Product/Gallery/Processor.php rename to app/code/Magento/MediaGalleryCatalog/Plugin/Product/Gallery/RemoveAssetAfterRemoveImage.php index 3fbe4e3a91a2b..865b40ce90a18 100644 --- a/app/code/Magento/MediaGallery/Plugin/Product/Gallery/Processor.php +++ b/app/code/Magento/MediaGalleryCatalog/Plugin/Product/Gallery/RemoveAssetAfterRemoveImage.php @@ -3,25 +3,24 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); -namespace Magento\MediaGallery\Plugin\Product\Gallery; +namespace Magento\MediaGalleryCatalog\Plugin\Product\Gallery; -use Magento\MediaGalleryApi\Model\Asset\Command\DeleteByPathInterface; +use Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Gallery\Processor as ProcessorSubject; use Psr\Log\LoggerInterface; /** - * Ensures that metadata is removed from the database when a product image has been deleted. + * Ensures that metadata is removed from the database when an image has been deleted (from legacy media gallery) */ -class Processor +class RemoveAssetAfterRemoveImage { /** - * @var DeleteByPathInterface + * @var DeleteAssetsByPathsInterface */ - private $deleteMediaAssetByPath; + private $deleteByPaths; /** * @var LoggerInterface @@ -31,14 +30,14 @@ class Processor /** * Processor constructor. * - * @param DeleteByPathInterface $deleteMediaAssetByPath + * @param DeleteAssetsByPathsInterface $deleteByPaths * @param LoggerInterface $logger */ public function __construct( - DeleteByPathInterface $deleteMediaAssetByPath, + DeleteAssetsByPathsInterface $deleteByPaths, LoggerInterface $logger ) { - $this->deleteMediaAssetByPath = $deleteMediaAssetByPath; + $this->deleteByPaths = $deleteByPaths; $this->logger = $logger; } @@ -49,7 +48,6 @@ public function __construct( * @param ProcessorSubject $result * @param Product $product * @param string $file - * * @return ProcessorSubject * * @SuppressWarnings(PHPMD.UnusedFormalParameter) @@ -65,7 +63,7 @@ public function afterRemoveImage( } try { - $this->deleteMediaAssetByPath->execute($file); + $this->deleteByPaths->execute([$file]); } catch (\Exception $exception) { $this->logger->critical($exception); } diff --git a/app/code/Magento/MediaGalleryCatalog/README.md b/app/code/Magento/MediaGalleryCatalog/README.md new file mode 100644 index 0000000000000..b39b1fae756d5 --- /dev/null +++ b/app/code/Magento/MediaGalleryCatalog/README.md @@ -0,0 +1,17 @@ +# Magento_MediaGalleryCatalog module + +The Magento_MediaGalleryCatalog module is responsible for for catalog gallery processor delete operation handling + +## Installation details + +For information about module installation in Magento 2, see [Enable or disable modules](https://devdocs.magento.com/guides/v2.3/install-gde/install/cli/install-cli-subcommands-enable.html). + +## Extensibility + +Extension developers can interact with the Magento_MediaGallery module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). + +[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_MediaGallery module. + +## Additional information + +For information about significant changes in patch releases, see [2.3.x Release information](https://devdocs.magento.com/guides/v2.3/release-notes/bk-release-notes.html). diff --git a/app/code/Magento/MediaGallery/Test/Unit/Plugin/Product/Gallery/ProcessorTest.php b/app/code/Magento/MediaGalleryCatalog/Test/Unit/Plugin/Product/Gallery/RemoveAssetAfterRemoveImageTest.php similarity index 75% rename from app/code/Magento/MediaGallery/Test/Unit/Plugin/Product/Gallery/ProcessorTest.php rename to app/code/Magento/MediaGalleryCatalog/Test/Unit/Plugin/Product/Gallery/RemoveAssetAfterRemoveImageTest.php index 94c3aaf5c2f19..7cb071a5aebe4 100644 --- a/app/code/Magento/MediaGallery/Test/Unit/Plugin/Product/Gallery/ProcessorTest.php +++ b/app/code/Magento/MediaGalleryCatalog/Test/Unit/Plugin/Product/Gallery/RemoveAssetAfterRemoveImageTest.php @@ -3,29 +3,28 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); -namespace Magento\MediaGallery\Test\Unit\Plugin\Product\Gallery; +namespace Magento\MediaGalleryCatalog\Test\Unit\Plugin\Product\Gallery; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Gallery\Processor as ProcessorSubject; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use Magento\MediaGallery\Plugin\Product\Gallery\Processor; -use Magento\MediaGalleryApi\Model\Asset\Command\DeleteByPathInterface; +use Magento\MediaGalleryCatalog\Plugin\Product\Gallery\RemoveAssetAfterRemoveImage; +use Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; /** - * Unit test for \Magento\MediaGallery\Plugin\Product\Gallery\Processor + * Unit test for \Magento\MediaGalleryCatalog\Plugin\Product\Gallery\Processor */ -class ProcessorTest extends TestCase +class RemoveAssetAfterRemoveImageTest extends TestCase { private const STUB_FILE_NAME = 'file'; /** - * @var DeleteByPathInterface|MockObject + * @var DeleteAssetsByPathsInterface|MockObject */ private $deleteMediaAssetByPathMock; @@ -45,7 +44,7 @@ class ProcessorTest extends TestCase private $productMock; /** - * @var Processor + * @var RemoveAssetAfterRemoveImage */ private $plugin; @@ -57,19 +56,13 @@ protected function setUp() $this->processorSubjectMock = $this->createMock(ProcessorSubject::class); $this->productMock = $this->createMock(Product::class); - $this->deleteMediaAssetByPathMock = $this->getMockBuilder(DeleteByPathInterface::class) - ->disableOriginalConstructor() - ->setMethods(['execute']) - ->getMockForAbstractClass(); - $this->loggerMock = $this->getMockBuilder(LoggerInterface::class) - ->disableOriginalConstructor() - ->setMethods(['critical']) - ->getMockForAbstractClass(); + $this->deleteMediaAssetByPathMock = $this->createMock(DeleteAssetsByPathsInterface::class); + $this->loggerMock = $this->createMock(LoggerInterface::class); $this->plugin = (new ObjectManagerHelper($this))->getObject( - Processor::class, + RemoveAssetAfterRemoveImage::class, [ - 'deleteMediaAssetByPath' => $this->deleteMediaAssetByPathMock, + 'deleteByPaths' => $this->deleteMediaAssetByPathMock, 'logger' => $this->loggerMock ] ); @@ -82,7 +75,7 @@ public function testAfterRemoveImageExpectsExecuteCalled() { $this->deleteMediaAssetByPathMock->expects($this->once()) ->method('execute') - ->with(self::STUB_FILE_NAME); + ->with([self::STUB_FILE_NAME]); $this->loggerMock->expects($this->never())->method('critical'); $actualResult = $this->plugin->afterRemoveImage( @@ -118,7 +111,7 @@ public function testAfterRemoveImageExpectsExecuteWillThrowException() { $this->deleteMediaAssetByPathMock->expects($this->once()) ->method('execute') - ->with(self::STUB_FILE_NAME) + ->with([self::STUB_FILE_NAME]) ->willThrowException(new \Exception('Some Exception')); $this->loggerMock->expects($this->once())->method('critical'); diff --git a/app/code/Magento/AuthorizenetGraphQl/composer.json b/app/code/Magento/MediaGalleryCatalog/composer.json similarity index 51% rename from app/code/Magento/AuthorizenetGraphQl/composer.json rename to app/code/Magento/MediaGalleryCatalog/composer.json index 2b54049bab434..ed3eb63ac970a 100644 --- a/app/code/Magento/AuthorizenetGraphQl/composer.json +++ b/app/code/Magento/MediaGalleryCatalog/composer.json @@ -1,15 +1,13 @@ { - "name": "magento/module-authorizenet-graph-ql", - "description": "N/A", - "type": "magento2-module", + "name": "magento/module-media-gallery-catalog", + "description": "Magento module responsible for catalog gallery processor delete operation handling", "require": { "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", - "magento/module-quote-graph-ql": "*" - }, - "suggest": { - "magento/module-graph-ql": "*" + "magento/module-media-gallery-api": "*", + "magento/module-catalog": "*" }, + "type": "magento2-module", "license": [ "OSL-3.0", "AFL-3.0" @@ -19,7 +17,7 @@ "registration.php" ], "psr-4": { - "Magento\\AuthorizenetGraphQl\\": "" + "Magento\\MediaGalleryCatalog\\": "" } } } diff --git a/app/code/Magento/MediaGalleryCatalog/etc/di.xml b/app/code/Magento/MediaGalleryCatalog/etc/di.xml new file mode 100644 index 0000000000000..bdfdf2c5ef959 --- /dev/null +++ b/app/code/Magento/MediaGalleryCatalog/etc/di.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\Catalog\Model\Product\Gallery\Processor"> + <plugin name="media_gallery_image_remove_metadata" type="Magento\MediaGalleryCatalog\Plugin\Product\Gallery\RemoveAssetAfterRemoveImage"/> + </type> +</config> diff --git a/app/code/Magento/MediaGalleryCatalog/etc/directory.xml b/app/code/Magento/MediaGalleryCatalog/etc/directory.xml new file mode 100644 index 0000000000000..eaced3f642f70 --- /dev/null +++ b/app/code/Magento/MediaGalleryCatalog/etc/directory.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_MediaGalleryApi:etc/directory.xsd"> + <blacklist> + <patterns> + <pattern name="catalog">/^catalog\/product/</pattern> + </patterns> + </blacklist> +</config> diff --git a/app/code/Magento/MediaGalleryCatalog/etc/module.xml b/app/code/Magento/MediaGalleryCatalog/etc/module.xml new file mode 100644 index 0000000000000..83f60ded3d35a --- /dev/null +++ b/app/code/Magento/MediaGalleryCatalog/etc/module.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_MediaGalleryCatalog"/> +</config> diff --git a/app/code/Magento/Authorizenet/registration.php b/app/code/Magento/MediaGalleryCatalog/registration.php similarity index 86% rename from app/code/Magento/Authorizenet/registration.php rename to app/code/Magento/MediaGalleryCatalog/registration.php index cb3bedaaee27d..3c24d0c298f38 100644 --- a/app/code/Magento/Authorizenet/registration.php +++ b/app/code/Magento/MediaGalleryCatalog/registration.php @@ -6,4 +6,4 @@ use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_Authorizenet', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_MediaGalleryCatalog', __DIR__); diff --git a/app/code/Magento/MediaStorage/composer.json b/app/code/Magento/MediaStorage/composer.json index ce97eec97f7c3..caee2bb9a802a 100644 --- a/app/code/Magento/MediaStorage/composer.json +++ b/app/code/Magento/MediaStorage/composer.json @@ -7,6 +7,7 @@ "require": { "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", + "magento/framework-bulk": "*", "magento/module-backend": "*", "magento/module-config": "*", "magento/module-store": "*", diff --git a/app/code/Magento/MessageQueue/composer.json b/app/code/Magento/MessageQueue/composer.json index 92744126900a4..14cf0eaaee0c6 100644 --- a/app/code/Magento/MessageQueue/composer.json +++ b/app/code/Magento/MessageQueue/composer.json @@ -6,6 +6,7 @@ }, "require": { "magento/framework": "*", + "magento/framework-message-queue": "*", "magento/magento-composer-installer": "*", "php": "~7.1.3||~7.2.0||~7.3.0" }, diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontGoCheckoutWithMultipleAddressesActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontGoCheckoutWithMultipleAddressesActionGroup.xml index fd57a3b095a3d..1d8e836041129 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontGoCheckoutWithMultipleAddressesActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontGoCheckoutWithMultipleAddressesActionGroup.xml @@ -9,6 +9,9 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="StorefrontGoCheckoutWithMultipleAddressesActionGroup"> + <waitForAjaxLoad stepKey="waitAjaxLoad"/> <click selector="{{MultishippingSection.shippingMultipleCheckout}}" stepKey="clickToMultipleAddressShippingButton"/> + <waitForPageLoad stepKey="waitForMultipleCheckoutLoad"/> + <seeElement selector="{{MultishippingSection.pageTitle}}" stepKey="seeMultipleCheckoutPageTitle"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml index fab513cc8d11a..db037d50f7dc6 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection/MultishippingSection.xml @@ -8,6 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="MultishippingSection"> + <element name="pageTitle" type="text" selector="//span[text()='Ship to Multiple Addresses']"/> <element name="checkoutWithMultipleAddresses" type="button" selector="//span[text()='Check Out with Multiple Addresses']"/> <element name="shippingMultipleCheckout" type="button" selector=".action.multicheckout"/> <element name="shippingAddressSelector" type="select" selector="//tr[position()={{addressPosition}}]//td[@data-th='Send To']//select" parameterized="true"/> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StoreFrontMyAccountWithMultishipmentTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StoreFrontMyAccountWithMultishipmentTest.xml deleted file mode 100644 index 312fa95bf77af..0000000000000 --- a/app/code/Magento/Multishipping/Test/Mftf/Test/StoreFrontMyAccountWithMultishipmentTest.xml +++ /dev/null @@ -1,117 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="StorefrontMyAccountWithMultishipmentTest"> - <annotations> - <features value="Multishipping"/> - <stories value="Shipping price shows 0 on Order view page after multiple address checkout"/> - <title value="DEPRECATED. Verify Shipping price for Storefront after multiple address checkout"/> - <description value="Verify that shipping price on My account matches with shipping method prices after multiple addresses checkout (Order view page)"/> - <severity value="CRITICAL"/> - <testCaseId value="MC-19303"/> - <group value="multishipping"/> - <skip> - <issueId value="DEPRECATED">Please use StorefrontOrderWithMultishippingTest instead</issueId> - </skip> - </annotations> - - <before> - <createData entity="SimpleSubCategory" stepKey="category"/> - <createData entity="SimpleProduct" stepKey="product1"> - <requiredEntity createDataKey="category"/> - </createData> - <createData entity="SimpleProduct" stepKey="product2"> - <requiredEntity createDataKey="category"/> - </createData> - <createData entity="Simple_US_Customer_Two_Addresses" stepKey="customer"/> - <!-- Set configurations --> - <magentoCLI command="config:set {{EnableMultiShippingCheckoutMultiple.path}} {{EnableMultiShippingCheckoutMultiple.value}}" stepKey="allowShippingToMultipleAddresses"/> - <magentoCLI command="config:set {{EnableFreeShippingMethod.path}} {{EnableFreeShippingMethod.value}}" stepKey="enableFreeShipping"/> - <magentoCLI command="config:set {{EnableFlatRateShippingMethod.path}} {{EnableFlatRateShippingMethod.value}}" stepKey="enableFlatRateShipping"/> - <magentoCLI command="config:set {{EnableCheckMoneyOrderPaymentMethod.path}} {{EnableCheckMoneyOrderPaymentMethod.value}}" stepKey="enableCheckMoneyOrderPaymentMethod"/> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> - <argument name="Customer" value="$$customer$$"/> - </actionGroup> - </before> - <after> - <actionGroup ref="StorefrontSignOutActionGroup" stepKey="customerLogout"/> - <magentoCLI command="config:set {{DisableMultiShippingCheckoutMultiple.path}} {{DisableMultiShippingCheckoutMultiple.value}}" stepKey="withdrawShippingToMultipleAddresses"/> - <deleteData createDataKey="category" stepKey="deleteCategory"/> - <deleteData createDataKey="product1" stepKey="deleteProduct1"/> - <deleteData createDataKey="product2" stepKey="deleteProduct2"/> - <deleteData createDataKey="customer" stepKey="deleteCustomer"/> - <magentoCLI command="config:set {{DisableFreeShippingMethod.path}} {{DisableFreeShippingMethod.value}}" stepKey="disableFreeShipping"/> - <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearAllFilters"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutAdmin"/> - </after> - <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addSimpleProduct1ToCart"> - <argument name="product" value="$$product1$$"/> - </actionGroup> - <waitForPageLoad stepKey="waitForSecondProductPageLoad"/> - <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addSimpleProduct2ToCart"> - <argument name="product" value="$$product2$$"/> - </actionGroup> - <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> - <actionGroup ref="CheckingWithMultipleAddressesActionGroup" stepKey="checkoutWithMultipleAddresses"/> - <waitForPageLoad stepKey="waitForShippingInfoPageLoad"/> - <actionGroup ref="SelectMultiShippingInfoActionGroup" stepKey="checkoutWithMultipleShipping"/> - <!--Select Check / Money order Payment method--> - <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectCheckMoneyPayment"/> - <actionGroup ref="SelectBillingInfoActionGroup" stepKey="checkoutWithPaymentMethod"/> - <waitForPageLoad stepKey="waitForReviewOrderPageLoad"/> - <actionGroup ref="ReviewOrderForMultiShipmentActionGroup" stepKey="reviewOrderForMultiShipment"> - <argument name="totalNameForFirstOrder" value="Shipping & Handling"/> - <argument name="totalPositionForFirstOrder" value="1"/> - <argument name="totalNameForSecondOrder" value="Shipping & Handling"/> - <argument name="totalPositionForSecondOrder" value="2"/> - </actionGroup> - <waitForPageLoad stepKey="waitForPlaceOrderPageLoad"/> - <actionGroup ref="StorefrontPlaceOrderForMultipleAddressesActionGroup" stepKey="placeOrder"> - <argument name="firstOrderPosition" value="1"/> - <argument name="secondOrderPosition" value="2"/> - </actionGroup> - <waitForPageLoad stepKey="waitForOrderPageLoad"/> - <amOnPage url="{{StorefrontCustomerOrdersHistoryPage.url}}" stepKey="goToSalesOrder"/> - <actionGroup ref="AssertStorefrontSalesOrderMatchesGrandTotalActionGroup" stepKey="checkSalesOrderForFirstOrder"> - <argument name="dataHref" value="$dataHrefForFirstOrderPlaceOrder"/> - </actionGroup> - <amOnPage url="{{StorefrontCustomerOrdersHistoryPage.url}}" stepKey="goToSalesOrder2"/> - <waitForPageLoad stepKey="waitForOrderPageLoad2"/> - <actionGroup ref="AssertStorefrontSalesOrderMatchesGrandTotalActionGroup" stepKey="checkSalesOrderForSecondOrder"> - <argument name="dataHref" value="$dataHrefForSecondOrderPlaceOrder"/> - </actionGroup> - <waitForPageLoad stepKey="waitForAdminPageToLoad"/> - <!-- Go to Stores > Configuration > Sales > Orders --> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onAdminOrdersPage"/> - <waitForPageLoad stepKey="waitForOrderPageLoad3"/> - <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearFilters"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoading"/> - <!--Assert order in orders grid --> - <!-- Go to order page --> - <actionGroup ref="OpenOrderByIdActionGroup" stepKey="openFirstOrderPage"> - <argument name="orderId" value="{$getFirstOrderIdPlaceOrder}"/> - </actionGroup> - <!-- Check status --> - <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeFirstOrderPendingStatus"/> - <actionGroup ref="AdminSalesOrderActionGroup" stepKey="validateOrderTotalsForFirstOrder"/> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onAdminOrdersPage2"/> - <waitForPageLoad stepKey="waitForOrderPageLoad4"/> - <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearFilters2"/> - <!-- Go to order page --> - <actionGroup ref="OpenOrderByIdActionGroup" stepKey="openSecondOrderPage"> - <argument name="orderId" value="{$getSecondOrderIdPlaceOrder}"/> - </actionGroup> - <!-- Check status --> - <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeSecondOrderPendingStatus"/> - <actionGroup ref="AdminSalesOrderActionGroup" stepKey="validateOrderTotalsForSecondOrder"/> - <amOnPage url="{{StorefrontHomePage.url}}" stepKey="gotToHomePage"/> - </test> -</tests> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml index 2925f2c5b1690..caf0ce3a51bae 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml @@ -59,9 +59,8 @@ <argument name="product" value="$$createSecondProduct$$"/> <argument name="productCount" value="2"/> </actionGroup> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnShoppingCartPage"/> <!-- Click 'Check Out with Multiple Addresses' --> - <waitForPageLoad stepKey="waitForSecondPageLoad"/> <actionGroup ref="StorefrontGoCheckoutWithMultipleAddressesActionGroup" stepKey="goCheckoutWithMultipleAddresses"/> <!-- Select different addresses and click 'Go to Shipping Information' --> <actionGroup ref="StorefrontCheckoutShippingSelectMultipleAddressesActionGroup" stepKey="selectMultipleAddresses"> @@ -71,7 +70,7 @@ <waitForPageLoad stepKey="waitPageLoad"/> <!-- Open the Cart page in another browser window and go back --> <openNewTab stepKey="openNewTab"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPageNewTab"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnShoppingCartPageNewTab"/> <actionGroup ref="AssertStorefrontCheckoutCartItemsActionGroup" stepKey="assertFirstProductItemInCheckOutCart"> <argument name="productName" value="$$createFirstProduct.name$$"/> <argument name="productSku" value="$$createFirstProduct.sku$$"/> diff --git a/app/code/Magento/MysqlMq/composer.json b/app/code/Magento/MysqlMq/composer.json index 413195c6f6d7c..a4e7443bf51f4 100644 --- a/app/code/Magento/MysqlMq/composer.json +++ b/app/code/Magento/MysqlMq/composer.json @@ -6,6 +6,7 @@ }, "require": { "magento/framework": "*", + "magento/framework-message-queue": "*", "magento/magento-composer-installer": "*", "magento/module-store": "*", "php": "~7.1.3||~7.2.0||~7.3.0" diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingCreateNewsletterTemplateActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingCreateNewsletterTemplateActionGroup.xml new file mode 100644 index 0000000000000..f7d0c59116af2 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingCreateNewsletterTemplateActionGroup.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!--Create New Template --> + <actionGroup name="AdminMarketingCreateNewsletterTemplateActionGroup"> + <arguments> + <argument name="name" type="string"/> + <argument name="subject" type="string"/> + <argument name="senderName" type="string"/> + <argument name="senderEmail" type="string"/> + <argument name="templateContent" type="string"/> + </arguments> + <!--Filling All Required Fields--> + <fillField stepKey="fillTemplateNameField" selector="{{BasicFieldNewsletterSection.templateName}}" userInput="{{name}}"/> + <fillField stepKey="fillTemplateSubjectField" selector="{{BasicFieldNewsletterSection.templateSubject}}" userInput="{{subject}}"/> + <fillField stepKey="fillSenderNameField" selector="{{BasicFieldNewsletterSection.senderName}}" userInput="{{senderName}}"/> + <fillField stepKey="fillSenderEmailField" selector="{{BasicFieldNewsletterSection.senderEmail}}" userInput="{{senderEmail}}"/> + <fillField stepKey="fillTemplateContentField" selector="{{NewsletterWYSIWYGSection.TextArea}}" userInput="{{templateContent}}"/> + <!--Saving Created Template--> + <click stepKey="clickSaveTemplateButton" selector="{{AdminNewsletterMainActionsSection.saveTemplateButton}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingDeleteNewsletterTemplateActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingDeleteNewsletterTemplateActionGroup.xml new file mode 100644 index 0000000000000..fd9c372388689 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingDeleteNewsletterTemplateActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!--Delete Newsletter Template --> + <actionGroup name="AdminMarketingDeleteNewsletterTemplateActionGroup"> + <click stepKey="clickDeleteButton" selector="{{AdminNewsletterMainActionsSection.deleteTemplateButton}}"/> + <click stepKey="confirmDelete" selector="{{AdminNewsletterMainActionsSection.confirmDelete}}"/> + <waitForPageLoad stepKey="waitForPageLoading"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingOpenNewsletterTemplateFromGridActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingOpenNewsletterTemplateFromGridActionGroup.xml new file mode 100644 index 0000000000000..0341e68cf2b13 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminMarketingOpenNewsletterTemplateFromGridActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminMarketingOpenNewsletterTemplateFromGridActionGroup"> + <click stepKey="openTemplate" selector="{{AdminNewsletterGridMainActionsSection.searchResultFirstRow}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminNavigateToCreateNewsletterTemplatePageActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminNavigateToCreateNewsletterTemplatePageActionGroup.xml new file mode 100644 index 0000000000000..6e965279a4cb0 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminNavigateToCreateNewsletterTemplatePageActionGroup.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminNavigateToCreateNewsletterTemplatePageActionGroup"> + <click stepKey="clickAddNewTemplateButton" selector="{{AdminNewsletterGridMainActionsSection.add}}"/> + <waitForPageLoad stepKey="waitForNewNewsletterTemplatesPageLoaded"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminSearchNewsletterTemplateOnGridActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminSearchNewsletterTemplateOnGridActionGroup.xml new file mode 100644 index 0000000000000..ac733a5c6ef62 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AdminSearchNewsletterTemplateOnGridActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + <!--Search Newsletter Template On Grid --> + <actionGroup name="AdminSearchNewsletterTemplateOnGridActionGroup"> + <arguments> + <argument name="name" type="string"/> + <argument name="subject" type="string"/> + </arguments> + <fillField userInput="{{name}}" selector="{{AdminNewsletterGridMainActionsSection.name}}" stepKey="filterName"/> + <fillField userInput="{{subject}}" selector="{{AdminNewsletterGridMainActionsSection.subject}}" stepKey="filterSubject"/> + <click stepKey="clickSearchButton" selector="{{AdminNewsletterGridMainActionsSection.search}}"/> + <waitForPageLoad stepKey="waitForNewNewsletterTemplatesPageLoadedAfterFiltering"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AssertAdminCreatedNewsletterTemplateInGridActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AssertAdminCreatedNewsletterTemplateInGridActionGroup.xml new file mode 100644 index 0000000000000..495ce1b09047b --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AssertAdminCreatedNewsletterTemplateInGridActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + <!--Search Newsletter Template On Grid --> + <actionGroup name="AssertAdminCreatedNewsletterTemplateInGridActionGroup"> + <arguments> + <argument name="name" type="string"/> + <argument name="subject" type="string"/> + </arguments> + + <see userInput="{{name}}" selector="{{AdminNewsletterGridMainActionsSection.newsletterGrid}}" stepKey="assertTemplatename"/> + <see userInput="{{subject}}" selector="{{AdminNewsletterGridMainActionsSection.newsletterGrid}}" stepKey="assertTemplateSubject"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AssertAdminNewsletterTemplateFormActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AssertAdminNewsletterTemplateFormActionGroup.xml new file mode 100644 index 0000000000000..a5a3bd217d135 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/AssertAdminNewsletterTemplateFormActionGroup.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertAdminNewsletterTemplateFormActionGroup"> + <arguments> + <argument name="name" type="string"/> + <argument name="subject" type="string"/> + <argument name="senderName" type="string"/> + <argument name="senderEmail" type="string"/> + <argument name="templateContent" type="string"/> + </arguments> + + <seeInField stepKey="seeTemplateNameField" userInput="{{name}}" selector="{{BasicFieldNewsletterSection.templateName}}"/> + <seeInField stepKey="seeTemplateSubjectField" userInput="{{subject}}" selector="{{BasicFieldNewsletterSection.templateSubject}}"/> + <seeInField stepKey="seeTemplateSenderNameField" userInput="{{senderName}}" selector="{{BasicFieldNewsletterSection.senderName}}"/> + <seeInField stepKey="seeTemplateSenderEmailField" userInput="{{senderEmail}}" selector="{{BasicFieldNewsletterSection.senderEmail}}"/> + <seeInField stepKey="seeTemplateContentField" userInput="{{templateContent}}" selector="{{NewsletterWYSIWYGSection.TextArea}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Data/NewsletterTemplateData.xml b/app/code/Magento/Newsletter/Test/Mftf/Data/NewsletterTemplateData.xml index fe2deed9a279f..8d3e87b17513d 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Data/NewsletterTemplateData.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Data/NewsletterTemplateData.xml @@ -13,5 +13,13 @@ <data key="subject">Test Newsletter Subject</data> <data key="senderName">Admin</data> <data key="senderEmail">admin@magento.com</data> + <data key="textAreaContent">Some Test Content</data> + </entity> + <entity name="updatedNewsletter" type="cms_page"> + <data key="name" unique="suffix">Updated Newsletter Template</data> + <data key="subject">Updated Newsletter Subject</data> + <data key="senderName">Admin</data> + <data key="senderEmail">admin@magento.com</data> + <data key="textAreaContent">Some Updated Test Content</data> </entity> </entities> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Section/AdminNewsletterGridMainActionsSection.xml b/app/code/Magento/Newsletter/Test/Mftf/Section/AdminNewsletterGridMainActionsSection.xml new file mode 100644 index 0000000000000..ed1b432f798a5 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/Section/AdminNewsletterGridMainActionsSection.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminNewsletterGridMainActionsSection"> + <element name="newsletterGrid" type="text" selector="table.data-grid"/> + <element name="add" type="button" selector=".page-actions .page-actions-buttons .add"/> + <element name="name" type="input" selector="[id$='filter_code']"/> + <element name="subject" type="input" selector="[id$='filter_subject']"/> + <element name="search" type="button" selector=".action-default.scalable.action-secondary"/> + <element name="resetFilter" type="button" selector=".action-default.scalable.action-reset.action-tertiary"/> + <element name="searchResultFirstRow" type="text" selector=".data-grid>tbody>tr"/> + <element name="messageByType" type="block" selector="#messages .message-{{messageType}}" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Section/AdminNewsletterMainActionsSection.xml b/app/code/Magento/Newsletter/Test/Mftf/Section/AdminNewsletterMainActionsSection.xml new file mode 100644 index 0000000000000..d824496f8e6b8 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/Section/AdminNewsletterMainActionsSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminNewsletterMainActionsSection"> + <element name="saveTemplateButton" type="button" selector=".page-actions-inner .page-actions-buttons .save"/> + <element name="deleteTemplateButton" type="button" selector=".page-actions-inner .page-actions-buttons .delete"/> + <element name="confirmDelete" type="button" selector=".action-primary.action-accept" timeout="10"/> + </section> +</sections> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingCreateNewsletterTemplateTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingCreateNewsletterTemplateTest.xml new file mode 100644 index 0000000000000..d3ebe3cbc30de --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingCreateNewsletterTemplateTest.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMarketingCreateNewsletterTemplateTest"> + <annotations> + <features value="Newsletter"/> + <stories value="Admin Creates Newsletter Template"/> + <title value="Newsletter Template Creation"/> + <description value="Newsletter Template Successfully Created"/> + <group value="newsletter"/> + <group value="mtf_migrated"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-29809"/> + <group value="WYSIWYGDisabled"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + </before> + <after> + <!-- Delete Created Newsletter Template --> + <actionGroup ref="AdminSearchNewsletterTemplateOnGridActionGroup" stepKey="findCreatedNewsletterTemplateInGrid"> + <argument name="name" value="{{_defaultNewsletter.name}}"/> + <argument name="subject" value="{{_defaultNewsletter.subject}}"/> + </actionGroup> + <actionGroup ref="AdminMarketingOpenNewsletterTemplateFromGridActionGroup" stepKey="openTemplate"/> + <actionGroup ref="AdminMarketingDeleteNewsletterTemplateActionGroup" stepKey="deleteTemplate"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + </after> + <!--TEST BODY --> + <!-- Navigate To MARKETING > Newsletter Template --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToNewsletterTemplatePage"> + <argument name="menuUiId" value="{{AdminMenuMarketing.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuMarketingCommunicationsNewsletterTemplate.dataUiId}}"/> + </actionGroup> + <!-- Navigate To Create Newsletter Template Page --> + <actionGroup ref="AdminNavigateToCreateNewsletterTemplatePageActionGroup" stepKey="navigateToCreateNewsletterPage"/> + <!-- Create Newsletter Template --> + <actionGroup ref="AdminMarketingCreateNewsletterTemplateActionGroup" stepKey="updateNewsletterTemplate"> + <argument name="name" value="{{_defaultNewsletter.name}}"/> + <argument name="subject" value="{{_defaultNewsletter.subject}}"/> + <argument name="senderName" value="{{_defaultNewsletter.senderName}}"/> + <argument name="senderEmail" value="{{_defaultNewsletter.senderEmail}}"/> + <argument name="templateContent" value="{{_defaultNewsletter.textAreaContent}}"/> + </actionGroup> + <!-- Assert Success Message --> + <actionGroup ref="AssertMessageInAdminPanelActionGroup" stepKey="seeSuccessMessage"> + <argument name="message" value="The newsletter template has been saved."/> + </actionGroup> + <!-- Find Created Newsletter On grid --> + <actionGroup ref="AdminSearchNewsletterTemplateOnGridActionGroup" stepKey="findCreatedNewsletterTemplate"> + <argument name="name" value="{{_defaultNewsletter.name}}"/> + <argument name="subject" value="{{_defaultNewsletter.subject}}"/> + </actionGroup> + <!-- Assert Created Newsletter on Grid --> + <actionGroup ref="AssertAdminCreatedNewsletterTemplateInGridActionGroup" stepKey="assertNewsletterInGrid"> + <argument name="name" value="{{_defaultNewsletter.name}}"/> + <argument name="subject" value="{{_defaultNewsletter.subject}}"/> + </actionGroup> + <!--END TEST BODY --> + </test> +</tests> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingNewsletterTemplateUpdateTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingNewsletterTemplateUpdateTest.xml new file mode 100644 index 0000000000000..82b6e1833a753 --- /dev/null +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingNewsletterTemplateUpdateTest.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMarketingNewsletterTemplateUpdateTest"> + <annotations> + <features value="Newsletter"/> + <stories value="Newsletter Updating"/> + <title value="Newsletter Updating Test"/> + <description value="Admin should be able update created Newsletter Template"/> + <group value="reports"/> + <group value="mtf_migrated"/> + <group value="WYSIWYGDisabled"/> + </annotations> + + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToNewsletterTemplatePage"> + <argument name="menuUiId" value="{{AdminMenuMarketing.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuMarketingCommunicationsNewsletterTemplate.dataUiId}}"/> + </actionGroup> + <actionGroup ref="AdminNavigateToCreateNewsletterTemplatePageActionGroup" stepKey="navigateTiCreateNewsletterTemplatePage"/> + <actionGroup ref="AdminMarketingCreateNewsletterTemplateActionGroup" stepKey="createNewsletterTemplate"> + <argument name="name" value="{{_defaultNewsletter.name}}"/> + <argument name="subject" value="{{_defaultNewsletter.subject}}"/> + <argument name="senderName" value="{{_defaultNewsletter.senderName}}"/> + <argument name="senderEmail" value="{{_defaultNewsletter.senderEmail}}"/> + <argument name="templateContent" value="{{_defaultNewsletter.textAreaContent}}"/> + </actionGroup> + <actionGroup ref="AdminSearchNewsletterTemplateOnGridActionGroup" stepKey="findCreatedNewsletterTemplate"> + <argument name="name" value="{{_defaultNewsletter.name}}"/> + <argument name="subject" value="{{_defaultNewsletter.subject}}"/> + </actionGroup> + <actionGroup ref="AdminMarketingOpenNewsletterTemplateFromGridActionGroup" stepKey="openCreatedNewsletterTemplate"/> + </before> + <after> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToNewsletterGridPage"> + <argument name="menuUiId" value="{{AdminMenuMarketing.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuMarketingCommunicationsNewsletterTemplate.dataUiId}}"/> + </actionGroup> + <actionGroup ref="AdminSearchNewsletterTemplateOnGridActionGroup" stepKey="findCreatedNewsletterTemplateInGrid"> + <argument name="name" value="{{updatedNewsletter.name}}"/> + <argument name="subject" value="{{updatedNewsletter.subject}}"/> + </actionGroup> + <actionGroup ref="AdminMarketingOpenNewsletterTemplateFromGridActionGroup" stepKey="openTemplate"/> + <actionGroup ref="AdminMarketingDeleteNewsletterTemplateActionGroup" stepKey="deleteTemplate"/> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + + <actionGroup ref="AdminMarketingCreateNewsletterTemplateActionGroup" stepKey="updateNewsletterTemplate"> + <argument name="name" value="{{updatedNewsletter.name}}"/> + <argument name="subject" value="{{updatedNewsletter.subject}}"/> + <argument name="senderName" value="{{updatedNewsletter.senderName}}"/> + <argument name="senderEmail" value="{{updatedNewsletter.senderEmail}}"/> + <argument name="templateContent" value="{{updatedNewsletter.textAreaContent}}"/> + </actionGroup> + <actionGroup ref="AssertMessageInAdminPanelActionGroup" stepKey="assertSuccessMessage"> + <argument name="message" value="The newsletter template has been saved."/> + <argument name="messageType" value="success"/> + </actionGroup> + <actionGroup ref="AdminSearchNewsletterTemplateOnGridActionGroup" stepKey="findCreatedNewsletterTemplate"> + <argument name="name" value="{{updatedNewsletter.name}}"/> + <argument name="subject" value="{{updatedNewsletter.subject}}"/> + </actionGroup> + <actionGroup ref="AssertAdminCreatedNewsletterTemplateInGridActionGroup" stepKey="assertNewsletterInGrid"> + <argument name="name" value="{{updatedNewsletter.name}}"/> + <argument name="subject" value="{{updatedNewsletter.subject}}"/> + </actionGroup> + <actionGroup ref="AdminSearchNewsletterTemplateOnGridActionGroup" stepKey="findUpdatedNewsletterTemplate"> + <argument name="name" value="Updated Newsletter Template"/> + <argument name="subject" value="Updated Newsletter Subject"/> + </actionGroup> + <actionGroup ref="AdminMarketingOpenNewsletterTemplateFromGridActionGroup" stepKey="openTemplate"/> + <actionGroup ref="AssertAdminNewsletterTemplateFormActionGroup" stepKey="assertNewsletterForm"> + <argument name="name" value="{{updatedNewsletter.name}}"/> + <argument name="subject" value="{{updatedNewsletter.subject}}"/> + <argument name="senderName" value="{{updatedNewsletter.senderName}}"/> + <argument name="senderEmail" value="{{updatedNewsletter.senderEmail}}"/> + <argument name="templateContent" value="{{updatedNewsletter.textAreaContent}}"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Block/Form/AbstractInstructionTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Block/Form/AbstractInstructionTest.php index bf77d1975ed53..e0dc15c66b284 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Block/Form/AbstractInstructionTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Block/Form/AbstractInstructionTest.php @@ -3,34 +3,41 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Block\Form; -class AbstractInstructionTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\View\Element\Template\Context; +use Magento\OfflinePayments\Block\Form\AbstractInstruction; +use Magento\Payment\Model\MethodInterface; +use PHPUnit\Framework\TestCase; + +class AbstractInstructionTest extends TestCase { /** - * @var \Magento\OfflinePayments\Block\Form\AbstractInstruction + * @var AbstractInstruction */ - protected $_model; + protected $model; - protected function setUp() + protected function setUp(): void { - $context = $this->createMock(\Magento\Framework\View\Element\Template\Context::class); - $this->_model = $this->getMockForAbstractClass( - \Magento\OfflinePayments\Block\Form\AbstractInstruction::class, + $context = $this->createMock(Context::class); + $this->model = $this->getMockForAbstractClass( + AbstractInstruction::class, ['context' => $context] ); } public function testGetInstructions() { - $method = $this->getMockBuilder(\Magento\Payment\Model\MethodInterface::class) + $method = $this->getMockBuilder(MethodInterface::class) ->getMockForAbstractClass(); $method->expects($this->once()) ->method('getConfigData') ->willReturn('instructions'); - $this->_model->setData('method', $method); + $this->model->setData('method', $method); - $this->assertEquals('instructions', $this->_model->getInstructions()); + $this->assertEquals('instructions', $this->model->getInstructions()); } } diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php index 27705c242a012..cf0491167bd28 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Block/Info/CheckmoTest.php @@ -3,22 +3,25 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Block\Info; use Magento\Framework\View\Element\Template\Context; use Magento\OfflinePayments\Block\Info\Checkmo; use Magento\Payment\Model\Info; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** * CheckmoTest contains list of test for block methods testing */ -class CheckmoTest extends \PHPUnit\Framework\TestCase +class CheckmoTest extends TestCase { /** * @var Info|MockObject */ - private $info; + private $infoMock; /** * @var Checkmo @@ -28,14 +31,14 @@ class CheckmoTest extends \PHPUnit\Framework\TestCase /** * @inheritdoc */ - protected function setUp() + protected function setUp(): void { $context = $this->getMockBuilder(Context::class) ->disableOriginalConstructor() ->setMethods([]) ->getMock(); - $this->info = $this->getMockBuilder(Info::class) + $this->infoMock = $this->getMockBuilder(Info::class) ->disableOriginalConstructor() ->setMethods(['getAdditionalInformation']) ->getMock(); @@ -51,11 +54,11 @@ protected function setUp() */ public function testGetPayableTo($details, $expected) { - $this->info->expects(static::at(0)) + $this->infoMock->expects(static::at(0)) ->method('getAdditionalInformation') ->with('payable_to') ->willReturn($details); - $this->block->setData('info', $this->info); + $this->block->setData('info', $this->infoMock); static::assertEquals($expected, $this->block->getPayableTo()); } @@ -80,11 +83,11 @@ public function getPayableToDataProvider() */ public function testGetMailingAddress($details, $expected) { - $this->info->expects(static::at(1)) + $this->infoMock->expects(static::at(1)) ->method('getAdditionalInformation') ->with('mailing_address') ->willReturn($details); - $this->block->setData('info', $this->info); + $this->block->setData('info', $this->infoMock); static::assertEquals($expected, $this->block->getMailingAddress()); } @@ -107,11 +110,11 @@ public function getMailingAddressDataProvider() public function testConvertAdditionalDataIsNeverCalled() { $mailingAddress = 'blah@blah.com'; - $this->info->expects(static::at(1)) + $this->infoMock->expects(static::at(1)) ->method('getAdditionalInformation') ->with('mailing_address') ->willReturn($mailingAddress); - $this->block->setData('info', $this->info); + $this->block->setData('info', $this->infoMock); // First we set the property $this->_mailingAddress $this->block->getMailingAddress(); diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Model/BanktransferTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Model/BanktransferTest.php index 873cf4f217857..f92ca76da43dd 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Model/BanktransferTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Model/BanktransferTest.php @@ -3,38 +3,49 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Model; -class BanktransferTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\OfflinePayments\Model\Banktransfer; +use Magento\Payment\Block\Info\Instructions; +use Magento\Payment\Helper\Data; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class BanktransferTest extends TestCase { /** - * @var \Magento\OfflinePayments\Model\Banktransfer + * @var Banktransfer */ - protected $_object; + private $object; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ - protected $_scopeConfig; + private $scopeConfigMock; - protected function setUp() + protected function setUp(): void { - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $eventManager = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); - $paymentDataMock = $this->createMock(\Magento\Payment\Helper\Data::class); - $this->_scopeConfig = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); - $this->_object = $objectManagerHelper->getObject( - \Magento\OfflinePayments\Model\Banktransfer::class, + $objectManagerHelper = new ObjectManager($this); + $eventManager = $this->createMock(ManagerInterface::class); + $paymentDataMock = $this->createMock(Data::class); + $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + $this->object = $objectManagerHelper->getObject( + Banktransfer::class, [ 'eventManager' => $eventManager, 'paymentData' => $paymentDataMock, - 'scopeConfig' => $this->_scopeConfig, + 'scopeConfig' => $this->scopeConfigMock, ] ); } public function testGetInfoBlockType() { - $this->assertEquals(\Magento\Payment\Block\Info\Instructions::class, $this->_object->getInfoBlockType()); + $this->assertEquals(Instructions::class, $this->object->getInfoBlockType()); } } diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Model/CashondeliveryTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Model/CashondeliveryTest.php index 271bb41967255..afe831b3e0a50 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Model/CashondeliveryTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Model/CashondeliveryTest.php @@ -3,40 +3,51 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Model; -class CashondeliveryTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\OfflinePayments\Model\Cashondelivery; +use Magento\Payment\Block\Info\Instructions; +use Magento\Payment\Helper\Data; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class CashondeliveryTest extends TestCase { /** - * @var \Magento\OfflinePayments\Model\Cashondelivery + * @var Cashondelivery */ - protected $_object; + private $object; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ - protected $_scopeConfig; + private $scopeConfigMock; - protected function setUp() + protected function setUp(): void { - $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $helper = new ObjectManager($this); - $eventManager = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); - $paymentDataMock = $this->createMock(\Magento\Payment\Helper\Data::class); + $eventManager = $this->createMock(ManagerInterface::class); + $paymentDataMock = $this->createMock(Data::class); - $this->_scopeConfig = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); - $this->_object = $helper->getObject( - \Magento\OfflinePayments\Model\Cashondelivery::class, + $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + $this->object = $helper->getObject( + Cashondelivery::class, [ 'eventManager' => $eventManager, 'paymentData' => $paymentDataMock, - 'scopeConfig' => $this->_scopeConfig, + 'scopeConfig' => $this->scopeConfigMock, ] ); } public function testGetInfoBlockType() { - $this->assertEquals(\Magento\Payment\Block\Info\Instructions::class, $this->_object->getInfoBlockType()); + $this->assertEquals(Instructions::class, $this->object->getInfoBlockType()); } } diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoConfigProviderTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoConfigProviderTest.php index 8d65146ec102b..dd359b979283a 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoConfigProviderTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoConfigProviderTest.php @@ -3,34 +3,46 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Model; -use Magento\OfflinePayments\Model\CheckmoConfigProvider; -use Magento\OfflinePayments\Model\Checkmo; use Magento\Framework\Escaper; +use Magento\OfflinePayments\Model\Checkmo; +use Magento\OfflinePayments\Model\CheckmoConfigProvider; +use Magento\Payment\Helper\Data as PaymentHelper; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class CheckmoConfigProviderTest extends \PHPUnit\Framework\TestCase +class CheckmoConfigProviderTest extends TestCase { - /** @var CheckmoConfigProvider */ - protected $model; + /** + * @var CheckmoConfigProvider + */ + private $model; - /** @var Checkmo|\PHPUnit_Framework_MockObject_MockObject */ - protected $methodMock; + /** + * @var Checkmo|MockObject + */ + private $methodMock; - /** @var Escaper|\PHPUnit_Framework_MockObject_MockObject */ - protected $escaperMock; + /** + * @var Escaper|MockObject + */ + private $escaperMock; - protected function setUp() + protected function setUp(): void { - $this->methodMock = $this->createMock(\Magento\OfflinePayments\Model\Checkmo::class); + $this->methodMock = $this->createMock(Checkmo::class); - $paymentHelperMock = $this->createMock(\Magento\Payment\Helper\Data::class); + /** @var PaymentHelper|MockObject $paymentHelperMock */ + $paymentHelperMock = $this->createMock(PaymentHelper::class); $paymentHelperMock->expects($this->once()) ->method('getMethodInstance') ->with(Checkmo::PAYMENT_METHOD_CHECKMO_CODE) ->willReturn($this->methodMock); - $this->escaperMock = $this->createMock(\Magento\Framework\Escaper::class); + $this->escaperMock = $this->createMock(Escaper::class); $this->escaperMock->expects($this->any()) ->method('escapeHtml') ->willReturnArgument(0); diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoTest.php index a636bee744b6b..d7eae294511fd 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Model/CheckmoTest.php @@ -3,56 +3,63 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Model; -class CheckmoTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Event\ManagerInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\OfflinePayments\Model\Checkmo; +use Magento\Payment\Helper\Data; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class CheckmoTest extends TestCase { /** - * @var \Magento\OfflinePayments\Model\Checkmo + * @var Checkmo */ - protected $_object; + private $object; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ - protected $_scopeConfig; + private $scopeConfigMock; - protected function setUp() + protected function setUp(): void { - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $eventManager = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); - $paymentDataMock = $this->createMock(\Magento\Payment\Helper\Data::class); - $this->_scopeConfig = $this->createPartialMock( - \Magento\Framework\App\Config\ScopeConfigInterface::class, - ['getValue', 'isSetFlag'] - ); - $this->_object = $objectManagerHelper->getObject( - \Magento\OfflinePayments\Model\Checkmo::class, + $objectManagerHelper = new ObjectManager($this); + $eventManager = $this->createMock(ManagerInterface::class); + $paymentDataMock = $this->createMock(Data::class); + $this->scopeConfigMock = $this->createPartialMock(ScopeConfigInterface::class, ['getValue', 'isSetFlag']); + $this->object = $objectManagerHelper->getObject( + Checkmo::class, [ 'eventManager' => $eventManager, 'paymentData' => $paymentDataMock, - 'scopeConfig' => $this->_scopeConfig, + 'scopeConfig' => $this->scopeConfigMock, ] ); } public function testGetPayableTo() { - $this->_object->setStore(1); - $this->_scopeConfig->expects($this->once()) + $this->object->setStore(1); + $this->scopeConfigMock->expects($this->once()) ->method('getValue') ->with('payment/checkmo/payable_to', 'store', 1) ->willReturn('payable'); - $this->assertEquals('payable', $this->_object->getPayableTo()); + $this->assertEquals('payable', $this->object->getPayableTo()); } public function testGetMailingAddress() { - $this->_object->setStore(1); - $this->_scopeConfig->expects($this->once()) + $this->object->setStore(1); + $this->scopeConfigMock->expects($this->once()) ->method('getValue') ->with('payment/checkmo/mailing_address', 'store', 1) ->willReturn('blah@blah.com'); - $this->assertEquals('blah@blah.com', $this->_object->getMailingAddress()); + $this->assertEquals('blah@blah.com', $this->object->getMailingAddress()); } } diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Model/InstructionsConfigProviderTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Model/InstructionsConfigProviderTest.php index 97a64d8ab59b9..821ad6e7555c5 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Model/InstructionsConfigProviderTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Model/InstructionsConfigProviderTest.php @@ -3,40 +3,54 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Model; use Magento\Framework\Escaper; use Magento\OfflinePayments\Model\Banktransfer; use Magento\OfflinePayments\Model\Cashondelivery; use Magento\OfflinePayments\Model\InstructionsConfigProvider; +use Magento\Payment\Helper\Data as PaymentHelper; use Magento\Payment\Model\Method\AbstractMethod; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class InstructionsConfigProviderTest extends \PHPUnit\Framework\TestCase +class InstructionsConfigProviderTest extends TestCase { - /** @var InstructionsConfigProvider */ - protected $model; + /** + * @var InstructionsConfigProvider + */ + private $model; - /** @var AbstractMethod|\PHPUnit_Framework_MockObject_MockObject */ - protected $methodOneMock; + /** + * @var AbstractMethod|MockObject + */ + private $methodOneMock; - /** @var AbstractMethod|\PHPUnit_Framework_MockObject_MockObject */ - protected $methodTwoMock; + /** + * @var AbstractMethod|MockObject + */ + private $methodTwoMock; - /** @var Escaper|\PHPUnit_Framework_MockObject_MockObject */ - protected $escaperMock; + /** + * @var Escaper|MockObject + */ + private $escaperMock; - protected function setUp() + protected function setUp(): void { $this->methodOneMock = $this->createPartialMock( - \Magento\Payment\Model\Method\AbstractMethod::class, + AbstractMethod::class, ['isAvailable', 'getInstructions'] ); $this->methodTwoMock = $this->createPartialMock( - \Magento\Payment\Model\Method\AbstractMethod::class, + AbstractMethod::class, ['isAvailable', 'getInstructions'] ); - $paymentHelperMock = $this->createMock(\Magento\Payment\Helper\Data::class); + /** @var PaymentHelper|MockObject $paymentHelperMock */ + $paymentHelperMock = $this->createMock(PaymentHelper::class); $paymentHelperMock->expects($this->exactly(2)) ->method('getMethodInstance') ->willReturnMap([ @@ -44,7 +58,7 @@ protected function setUp() [Cashondelivery::PAYMENT_METHOD_CASHONDELIVERY_CODE, $this->methodTwoMock], ]); - $this->escaperMock = $this->createMock(\Magento\Framework\Escaper::class); + $this->escaperMock = $this->createMock(Escaper::class); $this->escaperMock->expects($this->any()) ->method('escapeHtml') ->willReturnArgument(0); diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Model/PurchaseorderTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Model/PurchaseorderTest.php index 2eb204651fcf4..d16721a743abd 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Model/PurchaseorderTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Model/PurchaseorderTest.php @@ -3,11 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Model; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\DataObject; use Magento\Framework\Event\ManagerInterface as EventManagerInterface; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\OfflinePayments\Model\Purchaseorder; use Magento\Payment\Helper\Data as PaymentHelper; @@ -15,34 +18,36 @@ use Magento\Sales\Api\Data\OrderAddressInterface; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Model\Order\Payment; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class PurchaseorderTest extends \PHPUnit\Framework\TestCase +class PurchaseorderTest extends TestCase { /** * @var Purchaseorder */ - protected $_object; + private $object; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ - protected $_scopeConfig; + private $scopeConfigMock; - protected function setUp() + protected function setUp(): void { $objectManagerHelper = new ObjectManager($this); $eventManager = $this->createMock(EventManagerInterface::class); $paymentDataMock = $this->createMock(PaymentHelper::class); - $this->_scopeConfig = $this->createPartialMock( + $this->scopeConfigMock = $this->createPartialMock( ScopeConfigInterface::class, ['getValue', 'isSetFlag'] ); - $this->_object = $objectManagerHelper->getObject( + $this->object = $objectManagerHelper->getObject( Purchaseorder::class, [ 'eventManager' => $eventManager, 'paymentData' => $paymentDataMock, - 'scopeConfig' => $this->_scopeConfig, + 'scopeConfig' => $this->scopeConfigMock, ] ); } @@ -54,17 +59,16 @@ public function testAssignData() ]); $instance = $this->createMock(PaymentInfo::class); - $this->_object->setData('info_instance', $instance); - $result = $this->_object->assignData($data); - $this->assertEquals($result, $this->_object); + $this->object->setData('info_instance', $instance); + $result = $this->object->assignData($data); + $this->assertEquals($result, $this->object); } - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage Purchase order number is a required field. - */ public function testValidate() { + $this->expectException(LocalizedException::class); + $this->expectExceptionMessage('Purchase order number is a required field.'); + $data = new DataObject([]); $addressMock = $this->createMock(OrderAddressInterface::class); @@ -77,9 +81,9 @@ public function testValidate() $instance->expects($this->once())->method('getOrder')->willReturn($orderMock); - $this->_object->setData('info_instance', $instance); - $this->_object->assignData($data); + $this->object->setData('info_instance', $instance); + $this->object->assignData($data); - $this->_object->validate(); + $this->object->validate(); } } diff --git a/app/code/Magento/OfflinePayments/Test/Unit/Observer/BeforeOrderPaymentSaveObserverTest.php b/app/code/Magento/OfflinePayments/Test/Unit/Observer/BeforeOrderPaymentSaveObserverTest.php index 18f57269b616b..c7e7006b07c91 100644 --- a/app/code/Magento/OfflinePayments/Test/Unit/Observer/BeforeOrderPaymentSaveObserverTest.php +++ b/app/code/Magento/OfflinePayments/Test/Unit/Observer/BeforeOrderPaymentSaveObserverTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\OfflinePayments\Test\Unit\Observer; use Magento\Framework\Event; @@ -18,7 +20,7 @@ use PHPUnit\Framework\TestCase; /** - * Test class for \Magento\OfflinePayments\Observer\BeforeOrderPaymentSaveObserver + * @covers \Magento\OfflinePayments\Observer\BeforeOrderPaymentSaveObserver */ class BeforeOrderPaymentSaveObserverTest extends TestCase { @@ -52,7 +54,7 @@ class BeforeOrderPaymentSaveObserverTest extends TestCase /** * @inheritdoc */ - protected function setUp() + protected function setUp(): void { $objectManagerHelper = new ObjectManager($this); $this->paymentMock = $this->getMockBuilder(Payment::class) diff --git a/app/code/Magento/OfflineShipping/Test/Mftf/Test/StorefrontFreeShippingDisplayWithInclTaxOptionTest.xml b/app/code/Magento/OfflineShipping/Test/Mftf/Test/StorefrontFreeShippingDisplayWithInclTaxOptionTest.xml index d2e092283e9bd..114c53d215647 100644 --- a/app/code/Magento/OfflineShipping/Test/Mftf/Test/StorefrontFreeShippingDisplayWithInclTaxOptionTest.xml +++ b/app/code/Magento/OfflineShipping/Test/Mftf/Test/StorefrontFreeShippingDisplayWithInclTaxOptionTest.xml @@ -45,8 +45,7 @@ <argument name="product" value="$$createSimpleProduct$$"/> </actionGroup> <!-- Assert that taxes are applied correctly for CA --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForCart"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckout"/> <waitForElementVisible selector="{{CheckoutPaymentSection.tax}}" stepKey="waitForOverviewVisible"/> <waitForElement time="30" selector="{{CheckoutCartSummarySection.estimateShippingAndTaxForm}}" stepKey="waitForEstimateShippingAndTaxForm"/> <waitForElement time="30" selector="{{CheckoutCartSummarySection.shippingMethodForm}}" stepKey="waitForShippingMethodForm"/> diff --git a/app/code/Magento/PageCache/Model/Layout/DepersonalizePlugin.php b/app/code/Magento/PageCache/Model/Layout/DepersonalizePlugin.php index 52b304d994bb3..c3a5a19bc1c2a 100644 --- a/app/code/Magento/PageCache/Model/Layout/DepersonalizePlugin.php +++ b/app/code/Magento/PageCache/Model/Layout/DepersonalizePlugin.php @@ -3,39 +3,46 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\PageCache\Model\Layout; +use Magento\Framework\Event\Manager as EventManager; +use Magento\Framework\Message\Session as MessageSession; +use Magento\Framework\View\LayoutInterface; use Magento\PageCache\Model\DepersonalizeChecker; /** - * Class DepersonalizePlugin + * Depersonalize customer data. + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class DepersonalizePlugin { /** * @var DepersonalizeChecker */ - protected $depersonalizeChecker; + private $depersonalizeChecker; /** - * @var \Magento\Framework\Event\Manager + * @var EventManager */ - protected $eventManager; + private $eventManager; /** - * @var \Magento\Framework\Message\Session + * @var MessageSession */ - protected $messageSession; + private $messageSession; /** * @param DepersonalizeChecker $depersonalizeChecker - * @param \Magento\Framework\Event\Manager $eventManager - * @param \Magento\Framework\Message\Session $messageSession + * @param EventManager $eventManager + * @param MessageSession $messageSession */ public function __construct( DepersonalizeChecker $depersonalizeChecker, - \Magento\Framework\Event\Manager $eventManager, - \Magento\Framework\Message\Session $messageSession + EventManager $eventManager, + MessageSession $messageSession ) { $this->depersonalizeChecker = $depersonalizeChecker; $this->eventManager = $eventManager; @@ -43,19 +50,18 @@ public function __construct( } /** - * After generate Xml + * Change sensitive customer data if the depersonalization is needed. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @param \Magento\Framework\View\LayoutInterface $result - * @return \Magento\Framework\View\LayoutInterface + * @param LayoutInterface $subject + * @return void */ - public function afterGenerateXml(\Magento\Framework\View\LayoutInterface $subject, $result) + public function afterGenerateElements(LayoutInterface $subject) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->eventManager->dispatch('depersonalize_clear_session'); + // phpcs:ignore Magento2.Functions.DiscouragedFunction session_write_close(); $this->messageSession->clearStorage(); } - return $result; } } diff --git a/app/code/Magento/PageCache/Model/Layout/LayoutPlugin.php b/app/code/Magento/PageCache/Model/Layout/LayoutPlugin.php index b4d9cb2d5e076..762f393f2a1b9 100644 --- a/app/code/Magento/PageCache/Model/Layout/LayoutPlugin.php +++ b/app/code/Magento/PageCache/Model/Layout/LayoutPlugin.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\PageCache\Model\Layout; @@ -13,21 +14,19 @@ use Magento\PageCache\Model\Config; /** - * Class LayoutPlugin - * - * Plugin for Magento\Framework\View\Layout + * Append cacheable pages response headers. */ class LayoutPlugin { /** * @var Config */ - protected $config; + private $config; /** * @var ResponseInterface */ - protected $response; + private $response; /** * @var MaintenanceMode @@ -35,8 +34,6 @@ class LayoutPlugin private $maintenanceMode; /** - * Constructor - * * @param ResponseInterface $response * @param Config $config * @param MaintenanceMode $maintenanceMode @@ -52,24 +49,22 @@ public function __construct( } /** - * Set appropriate Cache-Control headers + * Set appropriate Cache-Control headers. * * We have to set public headers in order to tell Varnish and Builtin app that page should be cached * * @param Layout $subject - * @param mixed $result - * @return mixed + * @return void */ - public function afterGenerateXml(Layout $subject, $result) + public function afterGenerateElements(Layout $subject) { if ($subject->isCacheable() && !$this->maintenanceMode->isOn() && $this->config->isEnabled()) { $this->response->setPublicHeaders($this->config->getTtl()); } - return $result; } /** - * Retrieve all identities from blocks for further cache invalidation + * Retrieve all identities from blocks for further cache invalidation. * * @param Layout $subject * @param mixed $result @@ -92,6 +87,7 @@ public function afterGetOutput(Layout $subject, $result) $tags = array_unique(array_merge(...$tags)); $this->response->setHeader('X-Magento-Tags', implode(',', $tags)); } + return $result; } } diff --git a/app/code/Magento/PageCache/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/Layout/DepersonalizePluginTest.php index c9638a3d5b8f6..bf10de64ff365 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -3,81 +3,98 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\PageCache\Test\Unit\Model\Layout; +use Magento\Framework\Event\Manager; +use Magento\Framework\Message\Session; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\LayoutInterface; +use Magento\PageCache\Model\DepersonalizeChecker; +use Magento\PageCache\Model\Layout\DepersonalizePlugin; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + /** - * Class DepersonalizePluginTest + * Unit tests for \Magento\PageCache\Model\Layout\DepersonalizePlugin class. */ -class DepersonalizePluginTest extends \PHPUnit\Framework\TestCase +class DepersonalizePluginTest extends TestCase { /** - * @var \Magento\PageCache\Model\Layout\DepersonalizePlugin + * @var DepersonalizePlugin */ - protected $plugin; + private $plugin; /** - * @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject + * @var LayoutInterface|MockObject */ - protected $layoutMock; + private $layoutMock; /** - * @var \Magento\Framework\Event\Manager|\PHPUnit_Framework_MockObject_MockObject + * @var Manager|MockObject */ - protected $eventManagerMock; + private $eventManagerMock; /** - * @var \Magento\Framework\Message\Session|\PHPUnit_Framework_MockObject_MockObject + * @var Session|MockObject */ - protected $messageSessionMock; + private $messageSessionMock; /** - * @var \Magento\PageCache\Model\DepersonalizeChecker|\PHPUnit_Framework_MockObject_MockObject + * @var DepersonalizeChecker|MockObject */ - protected $depersonalizeCheckerMock; + private $depersonalizeCheckerMock; /** - * SetUp + * @inheritdoc */ protected function setUp() { - $this->layoutMock = $this->createMock(\Magento\Framework\View\Layout::class); - $this->eventManagerMock = $this->createMock(\Magento\Framework\Event\Manager::class); + $this->layoutMock = $this->getMockForAbstractClass(LayoutInterface::class); + $this->eventManagerMock = $this->createMock(Manager::class); $this->messageSessionMock = $this->createPartialMock( - \Magento\Framework\Message\Session::class, + Session::class, ['clearStorage'] ); - $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); - $this->plugin = new \Magento\PageCache\Model\Layout\DepersonalizePlugin( - $this->depersonalizeCheckerMock, - $this->eventManagerMock, - $this->messageSessionMock + $this->depersonalizeCheckerMock = $this->createMock(DepersonalizeChecker::class); + $this->plugin = (new ObjectManagerHelper($this))->getObject( + DepersonalizePlugin::class, + [ + 'depersonalizeChecker' => $this->depersonalizeCheckerMock, + 'eventManager' => $this->eventManagerMock, + 'messageSession' => $this->messageSessionMock, + ] ); } - public function testAfterGenerateXml() + /** + * Test afterGenerateElements method when depersonalization is needed. + * + * @return void + */ + public function testAfterGenerateElements(): void { - $expectedResult = $this->createMock(\Magento\Framework\View\Layout::class); - $this->eventManagerMock->expects($this->once()) ->method('dispatch') ->with($this->equalTo('depersonalize_clear_session')); $this->messageSessionMock->expects($this->once())->method('clearStorage'); $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $expectedResult); - $this->assertEquals($expectedResult, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } - public function testAfterGenerateXmlNoDepersonalize() + /** + * Test afterGenerateElements method when depersonalization is not needed. + * + * @return void + */ + public function testAfterGenerateElementsNoDepersonalize(): void { $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); - $this->eventManagerMock->expects($this->never()) - ->method('dispatch'); + $this->eventManagerMock->expects($this->never())->method('dispatch'); $this->messageSessionMock->expects($this->never())->method('clearStorage'); - $expectedResult = $this->createMock(\Magento\Framework\View\Layout::class); - $actualResult = $this->plugin->afterGenerateXml($this->layoutMock, $expectedResult); - $this->assertEquals($expectedResult, $actualResult); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } } diff --git a/app/code/Magento/PageCache/Test/Unit/Model/Layout/LayoutPluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/Layout/LayoutPluginTest.php index e2bc7f237ab0a..d5d6efa5e35ae 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/Layout/LayoutPluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/Layout/LayoutPluginTest.php @@ -3,54 +3,69 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\PageCache\Test\Unit\Model\Layout; -class LayoutPluginTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\MaintenanceMode; +use Magento\Framework\App\Response\Http; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\Layout; +use Magento\PageCache\Model\Config; +use Magento\PageCache\Model\Layout\LayoutPlugin; +use Magento\PageCache\Test\Unit\Block\Controller\StubBlock; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * Unit tests for \Magento\PageCache\Model\Layout\LayoutPlugin class. + */ +class LayoutPluginTest extends TestCase { /** - * @var \Magento\PageCache\Model\Layout\LayoutPlugin + * @var LayoutPlugin */ - protected $model; + private $model; /** - * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ResponseInterface|MockObject */ - protected $responseMock; + private $responseMock; /** - * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject + * @var Layout|MockObject */ - protected $layoutMock; + private $layoutMock; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface + * @var ScopeConfigInterface|MockObject */ - protected $configMock; + private $configMock; /** - * @var \Magento\Framework\App\MaintenanceMode|\PHPUnit\Framework\MockObject\MockObject + * @var MaintenanceMode|MockObject */ private $maintenanceModeMock; + /** + * @inheritdoc + */ protected function setUp() { - $this->layoutMock = $this->getMockForAbstractClass( - \Magento\Framework\View\Layout::class, - [], - '', - false, - true, - true, - ['isCacheable', 'getAllBlocks'] - ); - $this->responseMock = $this->createMock(\Magento\Framework\App\Response\Http::class); - $this->configMock = $this->createMock(\Magento\PageCache\Model\Config::class); - $this->maintenanceModeMock = $this->createMock(\Magento\Framework\App\MaintenanceMode::class); - - $this->model = new \Magento\PageCache\Model\Layout\LayoutPlugin( - $this->responseMock, - $this->configMock, - $this->maintenanceModeMock + $this->layoutMock = $this->createPartialMock(Layout::class, ['isCacheable', 'getAllBlocks']); + $this->responseMock = $this->createMock(Http::class); + $this->configMock = $this->createMock(Config::class); + $this->maintenanceModeMock = $this->createMock(MaintenanceMode::class); + + $this->model = (new ObjectManagerHelper($this))->getObject( + LayoutPlugin::class, + [ + 'response' => $this->responseMock, + 'config' => $this->configMock, + 'maintenanceMode' => $this->maintenanceModeMock, + ] ); } @@ -58,33 +73,31 @@ protected function setUp() * @param $cacheState * @param $layoutIsCacheable * @param $maintenanceModeIsEnabled - * - * @dataProvider afterGenerateXmlDataProvider + * @return void + * @dataProvider afterGenerateElementsDataProvider */ - public function testAfterGenerateXml($cacheState, $layoutIsCacheable, $maintenanceModeIsEnabled) + public function testAfterGenerateElements($cacheState, $layoutIsCacheable, $maintenanceModeIsEnabled): void { $maxAge = 180; - $result = 'test'; - $this->layoutMock->expects($this->once())->method('isCacheable')->will($this->returnValue($layoutIsCacheable)); - $this->configMock->expects($this->any())->method('isEnabled')->will($this->returnValue($cacheState)); - $this->maintenanceModeMock->expects($this->any())->method('isOn') - ->will($this->returnValue($maintenanceModeIsEnabled)); + $this->layoutMock->expects($this->once())->method('isCacheable')->willReturn($layoutIsCacheable); + $this->configMock->expects($this->any())->method('isEnabled')->willReturn($cacheState); + $this->maintenanceModeMock->expects($this->any())->method('isOn')->willReturn($maintenanceModeIsEnabled); if ($layoutIsCacheable && $cacheState && !$maintenanceModeIsEnabled) { - $this->configMock->expects($this->once())->method('getTtl')->will($this->returnValue($maxAge)); + $this->configMock->expects($this->once())->method('getTtl')->willReturn($maxAge); $this->responseMock->expects($this->once())->method('setPublicHeaders')->with($maxAge); } else { $this->responseMock->expects($this->never())->method('setPublicHeaders'); } - $output = $this->model->afterGenerateXml($this->layoutMock, $result); - $this->assertSame($result, $output); + + $this->assertEmpty($this->model->afterGenerateElements($this->layoutMock)); } /** * @return array */ - public function afterGenerateXmlDataProvider() + public function afterGenerateElementsDataProvider(): array { return [ 'Full_cache state is true, Layout is cache-able' => [true, true, false], @@ -101,14 +114,15 @@ public function afterGenerateXmlDataProvider() * @param $expectedTags * @param $configCacheType * @param $ttl + * @return void * @dataProvider afterGetOutputDataProvider */ - public function testAfterGetOutput($cacheState, $layoutIsCacheable, $expectedTags, $configCacheType, $ttl) + public function testAfterGetOutput($cacheState, $layoutIsCacheable, $expectedTags, $configCacheType, $ttl): void { $html = 'html'; $this->configMock->expects($this->any())->method('isEnabled')->will($this->returnValue($cacheState)); $blockStub = $this->createPartialMock( - \Magento\PageCache\Test\Unit\Block\Controller\StubBlock::class, + StubBlock::class, ['getIdentities'] ); $blockStub->setTtl($ttl); @@ -130,42 +144,42 @@ public function testAfterGetOutput($cacheState, $layoutIsCacheable, $expectedTag /** * @return array */ - public function afterGetOutputDataProvider() + public function afterGetOutputDataProvider(): array { $tags = 'identity1,identity2'; return [ 'Cacheable layout, Full_cache state is true' => [true, true, $tags, null, 0], 'Non-cacheable layout' => [true, false, null, null, 0], - 'Cacheable layout with Varnish' => [true, true, $tags, \Magento\PageCache\Model\Config::VARNISH, 0], + 'Cacheable layout with Varnish' => [true, true, $tags, Config::VARNISH, 0], 'Cacheable layout with Varnish, Full_cache state is false' => [ false, true, $tags, - \Magento\PageCache\Model\Config::VARNISH, + Config::VARNISH, 0, ], 'Cacheable layout with Varnish and esi' => [ true, true, null, - \Magento\PageCache\Model\Config::VARNISH, + Config::VARNISH, 100, ], - 'Cacheable layout with Builtin' => [true, true, $tags, \Magento\PageCache\Model\Config::BUILT_IN, 0], + 'Cacheable layout with Builtin' => [true, true, $tags, Config::BUILT_IN, 0], 'Cacheable layout with Builtin, Full_cache state is false' => [ false, true, $tags, - \Magento\PageCache\Model\Config::BUILT_IN, + Config::BUILT_IN, 0, ], 'Cacheable layout with Builtin and esi' => [ true, false, $tags, - \Magento\PageCache\Model\Config::BUILT_IN, + Config::BUILT_IN, 100, - ] + ], ]; } } diff --git a/app/code/Magento/Payment/Test/Mftf/ActionGroup/ApplyCouponOnPaymentPageActionGroup.xml b/app/code/Magento/Payment/Test/Mftf/ActionGroup/ApplyCouponOnPaymentPageActionGroup.xml index 0f22222b5f767..f069e6ac4a4d5 100644 --- a/app/code/Magento/Payment/Test/Mftf/ActionGroup/ApplyCouponOnPaymentPageActionGroup.xml +++ b/app/code/Magento/Payment/Test/Mftf/ActionGroup/ApplyCouponOnPaymentPageActionGroup.xml @@ -20,6 +20,7 @@ <fillField selector="{{ProductCardSection.addCode}}" userInput="{{couponCode}}" stepKey="TypeDiscountCode"/> <click selector="{{ProductCardSection.applyDiscount}}" stepKey="clickToApplyDiscount"/> <waitForPageLoad stepKey="WaitForDiscountToBeAdded"/> - <see selector="{{ProductCardSection.discountVerificationMsg}}" userInput="Your coupon was successfully applied" stepKey="discountApplyMessage"/> + <!-- Success message will change to display none so will check DOM instead --> + <seeElementInDOM selector="{{ProductCardSection.discountSuccessMsgInDOM}}" stepKey="discountApplyMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php b/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php index 71e0384c72f79..b97cf2aa1fc2a 100644 --- a/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php +++ b/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php @@ -7,7 +7,7 @@ namespace Magento\Payment\Ui\Component\Listing\Column\Method; /** - * Class Options + * Class Options for Listing Column Method */ class Options implements \Magento\Framework\Data\OptionSourceInterface { @@ -43,13 +43,6 @@ public function toOptionArray() $this->options = $this->paymentHelper->getPaymentMethodList(true, true); } - array_walk( - $this->options, - function (&$item) { - $item['__disableTmpl'] = true; - } - ); - return $this->options; } } diff --git a/app/code/Magento/Paypal/Model/Payflow/Transparent.php b/app/code/Magento/Paypal/Model/Payflow/Transparent.php index 44a9b6f73c80e..87cb0df7b0d7f 100644 --- a/app/code/Magento/Paypal/Model/Payflow/Transparent.php +++ b/app/code/Magento/Paypal/Model/Payflow/Transparent.php @@ -61,7 +61,7 @@ class Transparent extends Payflowpro implements TransparentInterface * * @var bool */ - protected $_canFetchTransactionInfo = false; + protected $_canFetchTransactionInfo = true; /** * @var ResponseValidator @@ -355,11 +355,11 @@ public function capture(InfoInterface $payment, $amount) * * @param InfoInterface $payment * @return bool - * @throws InvalidTransitionException * @throws LocalizedException */ public function acceptPayment(InfoInterface $payment) { + $this->validatePaymentTransaction($payment); if ($this->getConfigPaymentAction() === MethodInterface::ACTION_AUTHORIZE_CAPTURE) { $invoices = iterator_to_array($payment->getOrder()->getInvoiceCollection()); $invoice = count($invoices) ? reset($invoices) : null; @@ -387,6 +387,20 @@ public function denyPayment(InfoInterface $payment) return true; } + /** + * @inheritDoc + */ + public function fetchTransactionInfo(InfoInterface $payment, $transactionId) + { + $result = parent::fetchTransactionInfo($payment, $transactionId); + $this->_canFetchTransactionInfo = false; + if ($payment->getIsTransactionApproved()) { + $this->acceptPayment($payment); + } + + return $result; + } + /** * Marks payment as fraudulent. * @@ -444,4 +458,24 @@ private function getZeroAmountAuthorizationId(InfoInterface $payment): string { return (string)$payment->getAdditionalInformation(self::PNREF); } + + /** + * Validates payment transaction status on PayPal. + * + * @param InfoInterface $payment + * @throws LocalizedException + */ + private function validatePaymentTransaction(InfoInterface $payment): void + { + if ($payment->canFetchTransactionInfo()) { + $transactionId = $payment->getLastTransId(); + parent::fetchTransactionInfo($payment, $transactionId); + $this->_canFetchTransactionInfo = false; + if ($payment->getIsTransactionDenied()) { + throw new LocalizedException( + __('Payment can\'t be accepted since transaction was rejected by merchant.') + ); + } + } + } } diff --git a/app/code/Magento/Paypal/Model/SmartButtonConfig.php b/app/code/Magento/Paypal/Model/SmartButtonConfig.php index 59e4db6d84201..921dc4679b089 100644 --- a/app/code/Magento/Paypal/Model/SmartButtonConfig.php +++ b/app/code/Magento/Paypal/Model/SmartButtonConfig.php @@ -13,7 +13,7 @@ use Magento\Store\Model\ScopeInterface; /** - * Smart button config + * Smart button configuration. */ class SmartButtonConfig { @@ -96,7 +96,14 @@ public function getConfig(string $page): array private function getDisallowedFunding(): array { $disallowedFunding = $this->config->getValue('disable_funding_options'); - return $disallowedFunding ? explode(',', $disallowedFunding) : []; + $result = $disallowedFunding ? explode(',', $disallowedFunding) : []; + + // PayPal Guest Checkout Credit Card Icons only available when Guest Checkout option is enabled + if ($this->isPaypalGuestCheckoutAllowed() === false && !in_array('CARD', $result)) { + array_push($result, 'CARD'); + } + + return $result; } /** @@ -168,4 +175,14 @@ private function updateStyles(array $styles, string $page): array return $styles; } + + /** + * Returns if is allowed PayPal Guest Checkout. + * + * @return bool + */ + private function isPaypalGuestCheckoutAllowed(): bool + { + return $this->config->getValue('solution_type') === Config::EC_SOLUTION_TYPE_SOLE; + } } diff --git a/app/code/Magento/Paypal/Test/Unit/Model/SmartButtonConfigTest.php b/app/code/Magento/Paypal/Test/Unit/Model/SmartButtonConfigTest.php index 5aa3dee0874b2..4002c78bb0ecc 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/SmartButtonConfigTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/SmartButtonConfigTest.php @@ -12,11 +12,13 @@ use Magento\Paypal\Model\SmartButtonConfig; use Magento\Framework\Locale\ResolverInterface; use Magento\Paypal\Model\ConfigFactory; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** - * Class SmartButtonConfigTest + * Test for smart button config */ -class SmartButtonConfigTest extends \PHPUnit\Framework\TestCase +class SmartButtonConfigTest extends TestCase { /** * @var \Magento\Paypal\Model\SmartButtonConfig @@ -24,15 +26,18 @@ class SmartButtonConfigTest extends \PHPUnit\Framework\TestCase private $model; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $localeResolverMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $configMock; + /** + * @inheritdoc + */ protected function setUp() { $this->localeResolverMock = $this->getMockForAbstractClass(ResolverInterface::class); @@ -40,12 +45,12 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - /** @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject $scopeConfigMock */ + /** @var ScopeConfigInterface|MockObject $scopeConfigMock */ $scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class); $scopeConfigMock->method('isSetFlag') ->willReturn(true); - /** @var \PHPUnit_Framework_MockObject_MockObject $configFactoryMock */ + /** @var MockObject $configFactoryMock */ $configFactoryMock = $this->getMockBuilder(ConfigFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) @@ -65,6 +70,7 @@ protected function setUp() * * @param string $page * @param string $locale + * @param bool $isCustomize * @param string $disallowedFundings * @param string $layout * @param string $size @@ -73,6 +79,7 @@ protected function setUp() * @param string $color * @param string $installmentPeriodLabel * @param string $installmentPeriodLocale + * @param string $isPaypalGuestCheckoutEnabled * @param array $expected * @dataProvider getConfigDataProvider * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -89,13 +96,19 @@ public function testGetConfig( string $color, string $installmentPeriodLabel, string $installmentPeriodLocale, + string $isPaypalGuestCheckoutEnabled, array $expected = [] ) { - $this->localeResolverMock->expects($this->any())->method('getLocale')->willReturn($locale); + $this->localeResolverMock->method('getLocale')->willReturn($locale); $this->configMock->method('getValue')->will( $this->returnValueMap( [ ['merchant_id', null, 'merchant'], + [ + 'solution_type', + null, + $isPaypalGuestCheckoutEnabled ? Config::EC_SOLUTION_TYPE_SOLE : Config::EC_SOLUTION_TYPE_MARK + ], ['sandbox_flag', null, true], ['disable_funding_options', null, $disallowedFundings], ["{$page}_page_button_customize", null, $isCustomize], @@ -117,6 +130,8 @@ public function testGetConfig( } /** + * Get config data provider + * * @return array */ public function getConfigDataProvider() @@ -125,6 +140,8 @@ public function getConfigDataProvider() } /** + * Get default styles + * * @return array */ private function getDefaultStyles() @@ -133,6 +150,8 @@ private function getDefaultStyles() } /** + * Get allowed fundings + * * @return array */ private function getAllowedFundings() diff --git a/app/code/Magento/Paypal/Test/Unit/Model/_files/expected_config.php b/app/code/Magento/Paypal/Test/Unit/Model/_files/expected_config.php index 7256984ab5226..f17b9f9fb4979 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/_files/expected_config.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/_files/expected_config.php @@ -18,6 +18,7 @@ 'blue', 'my_label', 'mx', + true, [ 'merchantId' => 'merchant', 'environment' => 'sandbox', @@ -48,6 +49,7 @@ 'blue', 'my_label', 'br', + true, [ 'merchantId' => 'merchant', 'environment' => 'sandbox', @@ -78,6 +80,7 @@ 'blue', 'my_label', 'br', + true, [ 'merchantId' => 'merchant', 'environment' => 'sandbox', @@ -95,11 +98,11 @@ 'isGuestCheckoutAllowed' => true ] ], - 'mini_cart' => [ + 'product' => [ 'cart', 'en', false, - null, + 'CREDIT', 'horizontal', 'small', 'pillow', @@ -107,28 +110,29 @@ 'blue', 'my_label', 'br', + true, [ 'merchantId' => 'merchant', 'environment' => 'sandbox', 'locale' => 'en', - 'allowedFunding' => ['CREDIT', 'ELV'], - 'disallowedFunding' => [], + 'allowedFunding' => ['ELV'], + 'disallowedFunding' => ['CREDIT'], 'styles' => [ 'layout' => 'vertical', 'size' => 'responsive', 'color' => 'gold', 'shape' => 'rect', - 'label' => 'paypal' + 'label' => 'paypal', ], 'isVisibleOnProductPage' => false, 'isGuestCheckoutAllowed' => true ] ], - 'product' => [ + 'checkout_with_paypal_guest_checkout_disabled' => [ 'cart', - 'en', - false, - 'CREDIT', + 'en_BR', + true, + null, 'horizontal', 'small', 'pillow', @@ -136,21 +140,23 @@ 'blue', 'my_label', 'br', + false, [ 'merchantId' => 'merchant', 'environment' => 'sandbox', - 'locale' => 'en', - 'allowedFunding' => ['ELV'], - 'disallowedFunding' => ['CREDIT'], + 'locale' => 'en_BR', + 'allowedFunding' => ['CREDIT', 'ELV'], + 'disallowedFunding' => ['CARD'], 'styles' => [ - 'layout' => 'vertical', - 'size' => 'responsive', - 'color' => 'gold', - 'shape' => 'rect', - 'label' => 'paypal', + 'layout' => 'horizontal', + 'size' => 'small', + 'color' => 'blue', + 'shape' => 'pillow', + 'label' => 'installment', + 'installmentperiod' => 0 ], 'isVisibleOnProductPage' => false, 'isGuestCheckoutAllowed' => true ] - ] + ], ]; diff --git a/app/code/Magento/Paypal/i18n/en_US.csv b/app/code/Magento/Paypal/i18n/en_US.csv index 54dd611d49073..912b99e2e6427 100644 --- a/app/code/Magento/Paypal/i18n/en_US.csv +++ b/app/code/Magento/Paypal/i18n/en_US.csv @@ -739,3 +739,4 @@ User,User "Elektronisches Lastschriftverfahren - German ELV","Elektronisches Lastschriftverfahren - German ELV" "Please enter at least 0 and at most 65535","Please enter at least 0 and at most 65535" "Order is suspended as an account verification transaction is suspected to be fraudulent.","Order is suspended as an account verification transaction is suspected to be fraudulent." +"Payment can't be accepted since transaction was rejected by merchant.","Payment can't be accepted since transaction was rejected by merchant." diff --git a/app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php b/app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php index 3bb15a2625dbb..16c7be78456d1 100644 --- a/app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php +++ b/app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php @@ -3,54 +3,51 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Persistent\Model\Layout; +use Magento\Framework\View\LayoutInterface; use Magento\PageCache\Model\DepersonalizeChecker; +use Magento\Persistent\Model\Session as PersistentSession; /** - * Class DepersonalizePlugin + * Depersonalize customer data. */ class DepersonalizePlugin { /** * @var DepersonalizeChecker */ - protected $depersonalizeChecker; + private $depersonalizeChecker; /** - * @var \Magento\Persistent\Model\Session + * @var PersistentSession */ - protected $persistentSession; + private $persistentSession; /** - * Constructor - * * @param DepersonalizeChecker $depersonalizeChecker - * @param \Magento\Persistent\Model\Session $persistentSession + * @param PersistentSession $persistentSession */ public function __construct( DepersonalizeChecker $depersonalizeChecker, - \Magento\Persistent\Model\Session $persistentSession + PersistentSession $persistentSession ) { - $this->persistentSession = $persistentSession; $this->depersonalizeChecker = $depersonalizeChecker; + $this->persistentSession = $persistentSession; } /** - * After generate Xml + * Change sensitive customer data if the depersonalization is needed. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @param \Magento\Framework\View\LayoutInterface $result - * @return \Magento\Framework\View\LayoutInterface + * @param LayoutInterface $subject + * @return void */ - public function afterGenerateXml( - \Magento\Framework\View\LayoutInterface $subject, - \Magento\Framework\View\LayoutInterface $result - ) { + public function afterGenerateElements(LayoutInterface $subject) + { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->persistentSession->setCustomerId(null); } - - return $result; } } diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml index a2488d564001c..18e19c4276548 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Test/CheckShoppingCartBehaviorAfterSessionExpiredTest.xml @@ -27,8 +27,14 @@ <requiredEntity createDataKey="createCategory"/> </createData> <!-- Create new customer --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="Simple_US_Customer_NY"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <!--Add shipping information--> <actionGroup ref="EnterCustomerAddressInfoActionGroup" stepKey="enterAddressInfo"> diff --git a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyThatInformationAboutViewingComparisonWishlistIsPersistedUnderLongTermCookieTest.xml b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyThatInformationAboutViewingComparisonWishlistIsPersistedUnderLongTermCookieTest.xml index 461304ef7aeaa..e6fae229d29b1 100644 --- a/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyThatInformationAboutViewingComparisonWishlistIsPersistedUnderLongTermCookieTest.xml +++ b/app/code/Magento/Persistent/Test/Mftf/Test/StorefrontVerifyThatInformationAboutViewingComparisonWishlistIsPersistedUnderLongTermCookieTest.xml @@ -67,7 +67,7 @@ <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginCustomer"> <argument name="Customer" value="$$createCustomer$$"/> </actionGroup> - <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="checkWelcomeMessage"/> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="checkWelcomeMessage"/> <!--Open the details page of Simple Product 1, Simple Product 2 and add to cart, get to the category--> <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addSimpleProductProductToCart"> @@ -128,7 +128,7 @@ </actionGroup> <!--Place the order--> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToShoppingCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToShoppingCartPage"/> <actionGroup ref="PlaceOrderWithLoggedUserActionGroup" stepKey="placeOrder"> <argument name="shippingMethod" value="Flat Rate"/> </actionGroup> @@ -144,7 +144,7 @@ <!--Sign out and check that widgets persist the information about the items--> <actionGroup ref="StorefrontSignOutActionGroup" stepKey="logoutFromCustomerToCheckThatWidgetsPersist"/> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.custom_attributes[url_key]$$)}}" stepKey="openCategoryPageAfterLogoutFromCustomer"/> - <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="checkWelcomeMessageAfterLogoutFromCustomer"/> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="checkWelcomeMessageAfterLogoutFromCustomer"/> <seeElement selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="checkLinkNotYouAfterLogoutFromCustomer"/> <actionGroup ref="StorefrontAssertProductInRecentlyViewedWidgetActionGroup" stepKey="checkSimpleProductInRecentlyViewedWidgetAfterLogout"> @@ -164,7 +164,7 @@ <click selector="{{StorefrontPanelHeaderSection.notYouLink}}" stepKey="clickLinkNotYou"/> <waitForPageLoad stepKey="waitForPageLoadAfterClickLinkNotYou"/> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.custom_attributes[url_key]$$)}}" stepKey="openCategoryPageAfterClickNotYou"/> - <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="checkWelcomeMessageAfterClickLinkNotYou"/> + <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="checkWelcomeMessageAfterClickLinkNotYou"/> <dontSee selector="{{StorefrontWidgetsSection.widgetRecentlyViewedProductsGrid}}" userInput="$$createSimpleProduct.name$$" stepKey="dontSeeProductInRecentlyViewedWidget"/> <dontSee selector="{{StorefrontCustomerWishlistSidebarSection.ProductTitleByName($$createSimpleProduct.name$$)}}" stepKey="dontSeeProductInWishlistWidget"/> <dontSee selector="{{StorefrontWidgetsSection.widgetRecentlyComparedProductsGrid}}" userInput="$$createSimpleProduct.name$$" stepKey="dontSeeProductInRecentlyComparedWidget"/> @@ -175,7 +175,7 @@ <argument name="Customer" value="$$createCustomer$$"/> </actionGroup> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.custom_attributes[url_key]$$)}}" stepKey="openCategoryPageToCheckWidgets"/> - <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="checkWelcomeMessageAfterLogin"/> + <see userInput="Welcome, $$createCustomer.firstname$$ $$createCustomer.lastname$$!" selector="{{StorefrontPanelHeaderSection.welcomeMessage}}" stepKey="checkWelcomeMessageAfterLogin"/> <actionGroup ref="StorefrontCustomerCheckProductInWishlistSidebarActionGroup" stepKey="checkSimpleProductNameInWishlistSidebarAfterLogin"> <argument name="productVar" value="$$createSimpleProduct$$"/> diff --git a/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php index 9731811ea8a97..393e2d8ab7799 100644 --- a/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -3,117 +3,84 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Persistent\Test\Unit\Model\Layout; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\LayoutInterface; +use Magento\PageCache\Model\DepersonalizeChecker; +use Magento\Persistent\Model\Layout\DepersonalizePlugin; +use Magento\Persistent\Model\Session as PersistentSession; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + /** - * Class DepersonalizePluginTest + * Unit tests for \Magento\Persistent\Model\Layout\DepersonalizePlugin class. */ -class DepersonalizePluginTest extends \PHPUnit\Framework\TestCase +class DepersonalizePluginTest extends TestCase { /** - * @var \Magento\Persistent\Model\Session|\PHPUnit_Framework_MockObject_MockObject + * @var PersistentSession|MockObject */ - protected $persistentSessionMock; + private $persistentSessionMock; /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var DepersonalizePlugin */ - protected $objectManager; + private $plugin; /** - * @var \Magento\Persistent\Model\Layout\DepersonalizePlugin + * @var DepersonalizeChecker|MockObject */ - protected $plugin; + private $depersonalizeCheckerMock; /** - * @var \Magento\PageCache\Model\DepersonalizeChecker|\PHPUnit_Framework_MockObject_MockObject + * @var LayoutInterface|MockObject */ - protected $depersonalizeCheckerMock; + private $layoutMock; /** - * Set up - * - * @return void + * @inheritdoc */ protected function setUp() { - $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->persistentSessionMock = $this->createPartialMock( - \Magento\Persistent\Model\Session::class, - ['setCustomerId'] - ); + $this->layoutMock = $this->getMockForAbstractClass(LayoutInterface::class); + $this->persistentSessionMock = $this->createPartialMock(PersistentSession::class, ['setCustomerId']); + $this->depersonalizeCheckerMock = $this->createMock(DepersonalizeChecker::class); - $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - - $this->moduleManagerMock = $this->createPartialMock(\Magento\Framework\Module\Manager::class, ['isEnabled']); - $this->cacheConfigMock = $this->createPartialMock(\Magento\PageCache\Model\Config::class, ['isEnabled']); - $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); - - $this->plugin = $this->objectManager->getObject( - \Magento\Persistent\Model\Layout\DepersonalizePlugin::class, + $this->plugin = (new ObjectManagerHelper($this))->getObject( + DepersonalizePlugin::class, [ - 'persistentSession' => $this->persistentSessionMock, 'depersonalizeChecker' => $this->depersonalizeCheckerMock, + 'persistentSession' => $this->persistentSessionMock, ] ); } - public function testAfterGenerateXml() + /** + * Test afterGenerateElements method when depersonalization is needed. + * + * @return void + */ + public function testAfterGenerateElements(): void { - /** @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject $subjectMock */ - $subjectMock = $this->getMockForAbstractClass( - \Magento\Framework\View\LayoutInterface::class, - [], - '', - false, - true, - true, - ['isCacheable'] - ); - /** @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject $resultMock */ - $resultMock = $this->getMockForAbstractClass( - \Magento\Framework\View\LayoutInterface::class, - [], - '', - false, - true, - true, - [] - ); - $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); $this->persistentSessionMock->expects($this->once())->method('setCustomerId')->with(null); - $this->assertEquals($resultMock, $this->plugin->afterGenerateXml($subjectMock, $resultMock)); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } - public function testAfterGenerateXmlNoDepersonalize() + /** + * Test afterGenerateElements method when depersonalization is not needed. + * + * @return void + */ + public function testAfterGenerateElementsNoDepersonalize(): void { - /** @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject $subjectMock */ - $subjectMock = $this->getMockForAbstractClass( - \Magento\Framework\View\LayoutInterface::class, - [], - '', - false, - true, - true, - ['isCacheable'] - ); - /** @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject $resultMock */ - $resultMock = $this->getMockForAbstractClass( - \Magento\Framework\View\LayoutInterface::class, - [], - '', - false, - true, - true, - [] - ); - $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); $this->persistentSessionMock->expects($this->never())->method('setCustomerId'); - $this->assertEquals($resultMock, $this->plugin->afterGenerateXml($subjectMock, $resultMock)); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); } } diff --git a/app/code/Magento/Persistent/etc/di.xml b/app/code/Magento/Persistent/etc/di.xml index c28426b4f25bf..f49d4361acb52 100644 --- a/app/code/Magento/Persistent/etc/di.xml +++ b/app/code/Magento/Persistent/etc/di.xml @@ -12,7 +12,4 @@ <type name="Magento\Customer\CustomerData\Customer"> <plugin name="section_data" type="Magento\Persistent\Model\Plugin\CustomerData" /> </type> - <type name="Magento\Framework\App\Http\Context"> - <plugin name="persistent_page_cache_variation" type="Magento\Persistent\Model\Plugin\PersistentCustomerContext" /> - </type> </config> diff --git a/app/code/Magento/Persistent/etc/frontend/di.xml b/app/code/Magento/Persistent/etc/frontend/di.xml index 3c33f8a51c418..fae706fcc5808 100644 --- a/app/code/Magento/Persistent/etc/frontend/di.xml +++ b/app/code/Magento/Persistent/etc/frontend/di.xml @@ -49,4 +49,7 @@ </argument> </arguments> </type> + <type name="Magento\Framework\App\Http\Context"> + <plugin name="persistent_page_cache_variation" type="Magento\Persistent\Model\Plugin\PersistentCustomerContext" /> + </type> </config> diff --git a/app/code/Magento/ProductAlert/Controller/Add.php b/app/code/Magento/ProductAlert/Controller/Add.php index 9498fa0e3d802..f8291ee5ffe15 100644 --- a/app/code/Magento/ProductAlert/Controller/Add.php +++ b/app/code/Magento/ProductAlert/Controller/Add.php @@ -10,6 +10,9 @@ use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\App\RequestInterface; +/** + * Abstract controller for notifying. + */ abstract class Add extends Action { /** @@ -39,8 +42,8 @@ public function dispatch(RequestInterface $request) { if (!$this->customerSession->authenticate()) { $this->_actionFlag->set('', 'no-dispatch', true); - if (!$this->customerSession->getBeforeUrl()) { - $this->customerSession->setBeforeUrl($this->_redirect->getRefererUrl()); + if (!$this->customerSession->getBeforeAuthUrl()) { + $this->customerSession->setBeforeAuthUrl($this->_redirect->getRefererUrl()); } } return parent::dispatch($request); diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Email.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Email.php index d2f589374c225..09f3adc8e1296 100644 --- a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Email.php +++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Email.php @@ -8,18 +8,19 @@ namespace Magento\ProductAlert\Controller\Unsubscribe; +use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\App\Action\Context; use Magento\Framework\App\Action\HttpGetActionInterface; -use Magento\Framework\App\Action\Action; use Magento\Framework\View\Result\Page; use Magento\Framework\View\Result\PageFactory; +use Magento\ProductAlert\Controller\Unsubscribe as UnsubscribeController; /** * Unsubscribing from 'Back in stock Alert'. * * Is used to transform a Get request that triggered in the email into the Post request endpoint */ -class Email extends Action implements HttpGetActionInterface +class Email extends UnsubscribeController implements HttpGetActionInterface { /** * @var PageFactory @@ -29,13 +30,15 @@ class Email extends Action implements HttpGetActionInterface /** * @param Context $context * @param PageFactory $resultPageFactory + * @param CustomerSession $customerSession */ public function __construct( Context $context, - PageFactory $resultPageFactory + PageFactory $resultPageFactory, + CustomerSession $customerSession ) { $this->resultPageFactory = $resultPageFactory; - parent::__construct($context); + parent::__construct($context, $customerSession); } /** diff --git a/app/code/Magento/ProductAlert/view/frontend/layout/productalert_unsubscribe_email.xml b/app/code/Magento/ProductAlert/view/frontend/layout/productalert_unsubscribe_email.xml index 8666fb83e01e3..4b759514e4b7f 100644 --- a/app/code/Magento/ProductAlert/view/frontend/layout/productalert_unsubscribe_email.xml +++ b/app/code/Magento/ProductAlert/view/frontend/layout/productalert_unsubscribe_email.xml @@ -8,7 +8,7 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> - <block class="Magento\Framework\View\Element\Template" name="unsubscription_form" template="Magento_ProductAlert::email/email.phtml" /> + <block class="Magento\Framework\View\Element\Template" name="unsubscription_form" cacheable="false" template="Magento_ProductAlert::email/email.phtml" /> </referenceContainer> </body> </page> diff --git a/app/code/Magento/Quote/Model/Quote/Item/Compare.php b/app/code/Magento/Quote/Model/Quote/Item/Compare.php index 76ba324518dc1..abe8b0d966050 100644 --- a/app/code/Magento/Quote/Model/Quote/Item/Compare.php +++ b/app/code/Magento/Quote/Model/Quote/Item/Compare.php @@ -71,17 +71,14 @@ public function compare(Item $target, Item $compared) if ($target->getProductId() != $compared->getProductId()) { return false; } - $targetOptions = $this->getOptions($target); - $comparedOptions = $this->getOptions($compared); - if (array_diff_key($targetOptions, $comparedOptions) != array_diff_key($comparedOptions, $targetOptions) - ) { + $targetOptionByCode = $target->getOptionsByCode(); + $comparedOptionsByCode = $compared->getOptionsByCode(); + if (!$target->compareOptions($targetOptionByCode, $comparedOptionsByCode)) { return false; } - foreach ($targetOptions as $name => $value) { - if ($comparedOptions[$name] != $value) { - return false; - } + if (!$target->compareOptions($comparedOptionsByCode, $targetOptionByCode)) { + return false; } return true; } diff --git a/app/code/Magento/Quote/Model/ShippingMethodManagement.php b/app/code/Magento/Quote/Model/ShippingMethodManagement.php index 73a2a43b2581f..d9fa37c0185a9 100644 --- a/app/code/Magento/Quote/Model/ShippingMethodManagement.php +++ b/app/code/Magento/Quote/Model/ShippingMethodManagement.php @@ -3,20 +3,27 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Quote\Model; +use Magento\Customer\Api\AddressRepositoryInterface; use Magento\Customer\Api\Data\AddressInterfaceFactory; use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\Api\ExtensibleDataInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; use Magento\Framework\Reflection\DataObjectProcessor; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Api\Data\EstimateAddressInterface; +use Magento\Quote\Api\Data\ShippingMethodInterface; use Magento\Quote\Api\ShipmentEstimationInterface; +use Magento\Quote\Model\Cart\ShippingMethodConverter; +use Magento\Quote\Model\Quote\Address; +use Magento\Quote\Model\Quote\Address\Rate; +use Magento\Quote\Model\Quote\TotalsCollector; use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; /** @@ -33,21 +40,21 @@ class ShippingMethodManagement implements /** * Quote repository. * - * @var \Magento\Quote\Api\CartRepositoryInterface + * @var CartRepositoryInterface */ protected $quoteRepository; /** * Shipping method converter * - * @var \Magento\Quote\Model\Cart\ShippingMethodConverter + * @var ShippingMethodConverter */ protected $converter; /** * Customer Address repository * - * @var \Magento\Customer\Api\AddressRepositoryInterface + * @var AddressRepositoryInterface */ protected $addressRepository; @@ -57,7 +64,7 @@ class ShippingMethodManagement implements protected $totalsCollector; /** - * @var \Magento\Framework\Reflection\DataObjectProcessor $dataProcessor + * @var DataObjectProcessor $dataProcessor */ private $dataProcessor; @@ -79,19 +86,19 @@ class ShippingMethodManagement implements /** * Constructor * - * @param \Magento\Quote\Api\CartRepositoryInterface $quoteRepository + * @param CartRepositoryInterface $quoteRepository * @param Cart\ShippingMethodConverter $converter - * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository + * @param AddressRepositoryInterface $addressRepository * @param Quote\TotalsCollector $totalsCollector * @param AddressInterfaceFactory|null $addressFactory * @param QuoteAddressResource|null $quoteAddressResource * @param CustomerSession|null $customerSession */ public function __construct( - \Magento\Quote\Api\CartRepositoryInterface $quoteRepository, + CartRepositoryInterface $quoteRepository, Cart\ShippingMethodConverter $converter, - \Magento\Customer\Api\AddressRepositoryInterface $addressRepository, - \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector, + AddressRepositoryInterface $addressRepository, + TotalsCollector $totalsCollector, AddressInterfaceFactory $addressFactory = null, QuoteAddressResource $quoteAddressResource = null, CustomerSession $customerSession = null @@ -112,10 +119,10 @@ public function __construct( */ public function get($cartId) { - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); - /** @var \Magento\Quote\Model\Quote\Address $shippingAddress */ + /** @var Address $shippingAddress */ $shippingAddress = $quote->getShippingAddress(); if (!$shippingAddress->getCountryId()) { throw new StateException(__('The shipping address is missing. Set the address and try again.')); @@ -127,7 +134,7 @@ public function get($cartId) } $shippingAddress->collectShippingRates(); - /** @var \Magento\Quote\Model\Quote\Address\Rate $shippingRate */ + /** @var Rate $shippingRate */ $shippingRate = $shippingAddress->getShippingRateByCode($shippingMethod); if (!$shippingRate) { return null; @@ -142,7 +149,7 @@ public function getList($cartId) { $output = []; - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); // no methods applicable for empty carts or carts with virtual products @@ -169,7 +176,7 @@ public function getList($cartId) */ public function set($cartId, $carrierCode, $methodCode) { - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); try { $this->apply($cartId, $carrierCode, $methodCode); @@ -199,7 +206,7 @@ public function set($cartId, $carrierCode, $methodCode) */ public function apply($cartId, $carrierCode, $methodCode) { - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); if (0 == $quote->getItemsCount()) { throw new InputException( @@ -223,9 +230,9 @@ public function apply($cartId, $carrierCode, $methodCode) /** * @inheritDoc */ - public function estimateByAddress($cartId, \Magento\Quote\Api\Data\EstimateAddressInterface $address) + public function estimateByAddress($cartId, EstimateAddressInterface $address) { - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); // no methods applicable for empty carts or carts with virtual products @@ -241,7 +248,7 @@ public function estimateByAddress($cartId, \Magento\Quote\Api\Data\EstimateAddre */ public function estimateByExtendedAddress($cartId, AddressInterface $address) { - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); // no methods applicable for empty carts or carts with virtual products @@ -256,7 +263,7 @@ public function estimateByExtendedAddress($cartId, AddressInterface $address) */ public function estimateByAddressId($cartId, $addressId) { - /** @var \Magento\Quote\Model\Quote $quote */ + /** @var Quote $quote */ $quote = $this->quoteRepository->getActive($cartId); // no methods applicable for empty carts or carts with virtual products @@ -276,13 +283,13 @@ public function estimateByAddressId($cartId, $addressId) * @param string $postcode * @param int $regionId * @param string $region - * @param \Magento\Framework\Api\ExtensibleDataInterface|null $address - * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] An array of shipping methods. + * @param ExtensibleDataInterface|null $address + * @return ShippingMethodInterface[] An array of shipping methods. * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @deprecated 100.2.0 */ protected function getEstimatedRates( - \Magento\Quote\Model\Quote $quote, + Quote $quote, $country, $postcode, $regionId, @@ -301,9 +308,9 @@ protected function getEstimatedRates( /** * Get list of available shipping methods * - * @param \Magento\Quote\Model\Quote $quote - * @param \Magento\Framework\Api\ExtensibleDataInterface $address - * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] + * @param Quote $quote + * @param ExtensibleDataInterface $address + * @return ShippingMethodInterface[] */ private function getShippingMethods(Quote $quote, $address) { @@ -334,27 +341,31 @@ private function getShippingMethods(Quote $quote, $address) /** * Get transform address interface into Array * - * @param \Magento\Framework\Api\ExtensibleDataInterface $address + * @param ExtensibleDataInterface $address * @return array */ private function extractAddressData($address) { $className = \Magento\Customer\Api\Data\AddressInterface::class; - if ($address instanceof \Magento\Quote\Api\Data\AddressInterface) { - $className = \Magento\Quote\Api\Data\AddressInterface::class; + if ($address instanceof AddressInterface) { + $className = AddressInterface::class; } elseif ($address instanceof EstimateAddressInterface) { $className = EstimateAddressInterface::class; } - return $this->getDataObjectProcessor()->buildOutputDataArray( + + $addressData = $this->getDataObjectProcessor()->buildOutputDataArray( $address, $className ); + unset($addressData[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]); + + return $addressData; } /** * Gets the data object processor * - * @return \Magento\Framework\Reflection\DataObjectProcessor + * @return DataObjectProcessor * @deprecated 100.2.0 */ private function getDataObjectProcessor() diff --git a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml index 12427c2caec25..06ebb0ccf2ee3 100644 --- a/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml +++ b/app/code/Magento/Quote/Test/Mftf/Test/StorefrontGuestCheckoutDisabledProductTest.xml @@ -133,7 +133,7 @@ <argument name="product" value="$$createSimpleProduct2$$"/> <argument name="productCount" value="1"/> </actionGroup> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckoutCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckoutCartPage"/> <!-- Disabled via admin panel --> <openNewTab stepKey="openNewTab2"/> <!-- Find the first simple product that we just created using the product grid and go to its page --> diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php index c3e69237fc2bb..e5e267713f963 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php @@ -3,57 +3,65 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Quote\Test\Unit\Model\Quote\Item; +use Magento\Framework\Serialize\JsonValidator; +use Magento\Framework\Serialize\Serializer\Json; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Quote\Model\Quote\Item; +use Magento\Quote\Model\Quote\Item\Compare; +use Magento\Quote\Model\Quote\Item\Option; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + /** - * Class CompareTest + * Tests the class that is used to compare Quote Item Options */ -class CompareTest extends \PHPUnit\Framework\TestCase +class CompareTest extends TestCase { /** - * @var \Magento\Quote\Model\Quote\Item\Compare + * @var Compare */ private $helper; /** - * @var \Magento\Quote\Model\Quote\Item|\PHPUnit_Framework_MockObject_MockObject + * @var Item|MockObject */ private $itemMock; /** - * @var \Magento\Quote\Model\Quote\Item|\PHPUnit_Framework_MockObject_MockObject + * @var Item|MockObject */ private $comparedMock; /** - * @var \Magento\Quote\Model\Quote\Item\Option|\PHPUnit_Framework_MockObject_MockObject + * @var Option|MockObject */ private $optionMock; /** - * @var \Magento\Framework\Serialize\JsonValidator|\PHPUnit_Framework_MockObject_MockObject + * @var JsonValidator|MockObject */ private $jsonValidatorMock; /** - * test setUp + * @inheritdoc */ protected function setUp() { $this->itemMock = $this->createPartialMock( - \Magento\Quote\Model\Quote\Item::class, - ['__wakeup', 'getProductId', 'getOptions'] + Item::class, + ['__wakeup', 'getProductId', 'getOptions', 'getOptionsByCode'] ); $this->comparedMock = $this->createPartialMock( - \Magento\Quote\Model\Quote\Item::class, - ['__wakeup', 'getProductId', 'getOptions'] + Item::class, + ['__wakeup', 'getProductId', 'getOptions', 'getOptionsByCode'] ); $this->optionMock = $this->createPartialMock( - \Magento\Quote\Model\Quote\Item\Option::class, + Option::class, ['__wakeup', 'getCode', 'getValue'] ); - $serializer = $this->getMockBuilder(\Magento\Framework\Serialize\Serializer\Json::class) + $serializer = $this->getMockBuilder(Json::class) ->setMethods(['unserialize']) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -65,13 +73,13 @@ function ($value) { } ); - $this->jsonValidatorMock = $this->getMockBuilder(\Magento\Framework\Serialize\JsonValidator::class) + $this->jsonValidatorMock = $this->getMockBuilder(JsonValidator::class) ->disableOriginalConstructor() ->getMock(); - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $objectManagerHelper = new ObjectManager($this); $this->helper = $objectManagerHelper->getObject( - \Magento\Quote\Model\Quote\Item\Compare::class, + Compare::class, [ 'serializer' => $serializer, 'jsonValidator' => $this->jsonValidatorMock @@ -82,17 +90,17 @@ function ($value) { /** * @param string $code * @param mixed $value - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ protected function getOptionMock($code, $value) { $optionMock = clone $this->optionMock; - $optionMock->expects($this->once()) + $optionMock->expects($this->any()) ->method('getCode') - ->will($this->returnValue($code)); - $optionMock->expects($this->once()) + ->willReturn($code); + $optionMock->expects($this->any()) ->method('getValue') - ->will($this->returnValue($value)); + ->willReturn($value); return $optionMock; } @@ -103,10 +111,10 @@ public function testCompareDifferentProduct() { $this->itemMock->expects($this->once()) ->method('getProductId') - ->will($this->returnValue(1)); + ->willReturn(1); $this->itemMock->expects($this->once()) ->method('getProductId') - ->will($this->returnValue(2)); + ->willReturn(2); $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock)); } @@ -116,36 +124,47 @@ public function testCompareDifferentProduct() */ public function testCompareProductWithDifferentOptions() { + // Identical Product Ids $this->itemMock->expects($this->any()) ->method('getProductId') - ->will($this->returnValue(1)); + ->willReturn(1); $this->comparedMock->expects($this->any()) ->method('getProductId') - ->will($this->returnValue(1)); + ->willReturn(1); + // Identical Option Keys $this->itemMock->expects($this->any()) ->method('getOptions') - ->will( - $this->returnValue( - [ - $this->getOptionMock('option-1', 1), - $this->getOptionMock('option-2', 'option-value'), - $this->getOptionMock('option-3', json_encode(['value' => 'value-1', 'qty' => 2])) - ] - ) - ); + ->willReturn([$this->getOptionMock('identical', 'value')]); $this->comparedMock->expects($this->any()) ->method('getOptions') - ->will($this->returnValue( + ->willReturn([$this->getOptionMock('identical', 'value')]); + + // Different Option Values + $this->itemMock->expects($this->once()) + ->method('getOptionsByCode') + ->willReturn( [ - $this->getOptionMock('option-4', 1), - $this->getOptionMock('option-2', 'option-value'), - $this->getOptionMock('option-3', json_encode([ - 'value' => 'value-1', - 'qty' => 2, - ])), + 'info_buyRequest' => $this->getOptionMock('info_buyRequest', ['value-1']), + 'option' => $this->getOptionMock('option', 1), + 'simple_product' => $this->getOptionMock('simple_product', 3), + 'product_qty_2' => $this->getOptionMock('product_qty_2', 10), + 'attributes' => $this->getOptionMock('attributes', 93), ] - )); + ); + + $this->comparedMock->expects($this->once()) + ->method('getOptionsByCode') + ->willReturn( + [ + 'info_buyRequest' => $this->getOptionMock('info_buyRequest', ['value-2']), + 'option' => $this->getOptionMock('option', 1), + 'simple_product' => $this->getOptionMock('simple_product', 3), + 'product_qty_2' => $this->getOptionMock('product_qty_2', 10), + 'attributes' => $this->getOptionMock('attributes', 94), + ] + ); + $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock)); } @@ -156,24 +175,24 @@ public function testCompareItemWithComparedWithoutOption() { $this->itemMock->expects($this->any()) ->method('getProductId') - ->will($this->returnValue(1)); + ->willReturn(1); $this->comparedMock->expects($this->any()) ->method('getProductId') - ->will($this->returnValue(1)); - $this->itemMock->expects($this->any()) - ->method('getOptions') - ->will( - $this->returnValue( - [ - $this->getOptionMock('option-1', 1), - $this->getOptionMock('option-2', 'option-value'), - $this->getOptionMock('option-3', json_encode(['value' => 'value-1', 'qty' => 2])), - ] - ) + ->willReturn(1); + $this->itemMock->expects($this->once()) + ->method('getOptionsByCode') + ->willReturn( + [ + 'info_buyRequest' => $this->getOptionMock('info_buyRequest', ['value-1']), + 'option' => $this->getOptionMock('option', 1), + 'simple_product' => $this->getOptionMock('simple_product', 3), + 'product_qty_2' => $this->getOptionMock('product_qty_2', 10), + 'attributes' => $this->getOptionMock('attributes', 93), + ] ); $this->comparedMock->expects($this->any()) - ->method('getOptions') - ->will($this->returnValue([])); + ->method('getOptionsByCode') + ->willReturn([]); $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock)); } @@ -184,62 +203,24 @@ public function testCompareItemWithoutOptionWithCompared() { $this->itemMock->expects($this->any()) ->method('getProductId') - ->will($this->returnValue(1)); + ->willReturn(1); $this->comparedMock->expects($this->any()) ->method('getProductId') - ->will($this->returnValue(1)); - $this->comparedMock->expects($this->any()) - ->method('getOptions') - ->will($this->returnValue( - [ - $this->getOptionMock('option-1', 1), - $this->getOptionMock('option-2', 'option-value'), - $this->getOptionMock( - 'option-3', - json_encode(['value' => 'value-1', 'qty' => 2]) - ), - ] - )); - $this->itemMock->expects($this->any()) - ->method('getOptions') - ->will($this->returnValue([])); - $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock)); - } - - /** - * Verify that compare ignores empty options. - */ - public function testCompareWithEmptyValues() - { - $itemOptionValue = '{"non-empty-option":"test","empty_option":""}'; - $comparedOptionValue = '{"non-empty-option":"test"}'; - - $this->jsonValidatorMock->expects($this->any()) - ->method('isValid') - ->willReturn(true); - - $this->itemMock->expects($this->any()) - ->method('getProductId') - ->will($this->returnValue(1)); - $this->comparedMock->expects($this->any()) - ->method('getProductId') - ->will($this->returnValue(1)); - - $this->itemMock->expects($this->once()) - ->method('getOptions') - ->willReturn( - [ - $this->getOptionMock('option-1', $itemOptionValue) - ] - ); + ->willReturn(1); $this->comparedMock->expects($this->once()) - ->method('getOptions') + ->method('getOptionsByCode') ->willReturn( [ - $this->getOptionMock('option-1', $comparedOptionValue) + 'info_buyRequest' => $this->getOptionMock('info_buyRequest', ['value-2']), + 'option' => $this->getOptionMock('option', 1), + 'simple_product' => $this->getOptionMock('simple_product', 3), + 'product_qty_2' => $this->getOptionMock('product_qty_2', 10), + 'attributes' => $this->getOptionMock('attributes', 94), ] ); - - $this->assertTrue($this->helper->compare($this->itemMock, $this->comparedMock)); + $this->itemMock->expects($this->any()) + ->method('getOptionsByCode') + ->willReturn([]); + $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock)); } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php index 34d7707d31666..c5b0b264bb79c 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php @@ -1,14 +1,19 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Quote\Test\Unit\Model; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\Data\AddressInterface; +use Magento\Customer\Api\Data\AddressInterfaceFactory; +use Magento\Framework\Api\ExtensibleDataInterface; +use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Api\Data\ShippingMethodInterface; +use Magento\Quote\Api\Data\ShippingMethodInterfaceFactory; use Magento\Quote\Model\Cart\ShippingMethodConverter; use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\Address; @@ -18,12 +23,13 @@ use Magento\Quote\Model\ResourceModel\Quote\Address as QuoteAddressResource; use Magento\Quote\Model\ShippingMethodManagement; use Magento\Store\Model\Store; -use PHPUnit_Framework_MockObject_MockObject as MockObject; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class ShippingMethodManagementTest extends \PHPUnit\Framework\TestCase +class ShippingMethodManagementTest extends TestCase { /** * @var ShippingMethodManagement @@ -31,12 +37,12 @@ class ShippingMethodManagementTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $shippingMethodMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $methodDataFactoryMock; @@ -46,7 +52,7 @@ class ShippingMethodManagementTest extends \PHPUnit\Framework\TestCase protected $converter; /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var ObjectManager */ protected $objectManager; @@ -66,17 +72,17 @@ class ShippingMethodManagementTest extends \PHPUnit\Framework\TestCase private $shippingAddress; /** - * @var \Magento\Framework\Reflection\DataObjectProcessor|MockObject + * @var DataObjectProcessor|MockObject */ private $dataProcessor; /** - * @var \Magento\Customer\Api\Data\AddressInterfaceFactory|MockObject + * @var AddressInterfaceFactory|MockObject */ private $addressFactory; /** - * @var \Magento\Customer\Api\AddressRepositoryInterface|MockObject + * @var AddressRepositoryInterface|MockObject */ private $addressRepository; @@ -95,19 +101,22 @@ class ShippingMethodManagementTest extends \PHPUnit\Framework\TestCase */ private $quoteAddressResource; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = new ObjectManager($this); - $this->quoteRepository = $this->createMock(\Magento\Quote\Api\CartRepositoryInterface::class); - $this->addressRepository = $this->createMock(\Magento\Customer\Api\AddressRepositoryInterface::class); + $this->quoteRepository = $this->createMock(CartRepositoryInterface::class); + $this->addressRepository = $this->createMock(AddressRepositoryInterface::class); - $className = \Magento\Quote\Api\Data\ShippingMethodInterfaceFactory::class; + $className = ShippingMethodInterfaceFactory::class; $this->methodDataFactoryMock = $this->createPartialMock($className, ['create']); - $className = \Magento\Customer\Api\Data\AddressInterfaceFactory::class; + $className = AddressInterfaceFactory::class; $this->addressFactory = $this->createPartialMock($className, ['create']); - $className = \Magento\Framework\Reflection\DataObjectProcessor::class; + $className = DataObjectProcessor::class; $this->dataProcessor = $this->createMock($className); $this->quoteAddressResource = $this->createMock(QuoteAddressResource::class); @@ -196,6 +205,9 @@ public function testGetMethodWhenShippingAddressIsNotSet() $this->assertNull($this->model->get($cartId)); } + /** + * Test to returns selected shipping method for a specified quote + */ public function testGetMethod() { $cartId = 666; @@ -213,14 +225,14 @@ public function testGetMethod() ->method('getShippingMethod')->will($this->returnValue('one_two')); $this->shippingAddress->expects($this->once())->method('collectShippingRates')->willReturnSelf(); - $shippingRateMock = $this->createMock(\Magento\Quote\Model\Quote\Address\Rate::class); + $shippingRateMock = $this->createMock(Rate::class); $this->shippingAddress->expects($this->once()) ->method('getShippingRateByCode') ->with('one_two') ->willReturn($shippingRateMock); - $this->shippingMethodMock = $this->createMock(\Magento\Quote\Api\Data\ShippingMethodInterface::class); + $this->shippingMethodMock = $this->createMock(ShippingMethodInterface::class); $this->converter->expects($this->once()) ->method('modelToDataObject') ->with($shippingRateMock, $currencyCode) @@ -228,6 +240,9 @@ public function testGetMethod() $this->model->get($cartId); } + /** + * Test to returns selected shipping method for a specified quote if method isn't set + */ public function testGetMethodIfMethodIsNotSet() { $cartId = 666; @@ -245,6 +260,9 @@ public function testGetMethodIfMethodIsNotSet() $this->assertNull($this->model->get($cartId)); } + /** + * Test to get lists applicable shipping methods for a specified quote + */ public function testGetListForVirtualCart() { $cartId = 834; @@ -256,6 +274,9 @@ public function testGetListForVirtualCart() $this->assertEquals([], $this->model->getList($cartId)); } + /** + * Test to get lists applicable shipping methods for a specified quote + */ public function testGetListForEmptyCart() { $cartId = 834; @@ -289,6 +310,9 @@ public function testGetListWhenShippingAddressIsNotSet() $this->model->getList($cartId); } + /** + * Test to get lists applicable shipping methods for a specified quote + */ public function testGetList() { $cartId = 834; @@ -302,7 +326,7 @@ public function testGetList() ->method('getShippingAddress')->will($this->returnValue($this->shippingAddress)); $this->shippingAddress->expects($this->once())->method('getCountryId')->will($this->returnValue(345)); $this->shippingAddress->expects($this->once())->method('collectShippingRates'); - $shippingRateMock = $this->createMock(\Magento\Quote\Model\Quote\Address\Rate::class); + $shippingRateMock = $this->createMock(Rate::class); $this->shippingAddress->expects($this->once()) ->method('getGroupedAllShippingRates') ->will($this->returnValue([[$shippingRateMock]])); @@ -441,6 +465,9 @@ public function testSetMethodWithoutAddress() $this->model->set($cartId, $carrierCode, $methodCode); } + /** + * Test to sets the carrier and shipping methods codes for a specified cart + */ public function testSetMethod() { $cartId = 12; @@ -472,6 +499,9 @@ public function testEstimateByExtendedAddress() { $cartId = 1; + $addressExtAttr = [ + 'discounts' => 100 + ]; $addressData = [ 'region' => 'California', 'region_id' => 23, @@ -509,7 +539,9 @@ public function testEstimateByExtendedAddress() $this->dataProcessor->expects(static::any()) ->method('buildOutputDataArray') - ->willReturn($addressData); + ->willReturn($addressData + [ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY => $addressExtAttr]); + + $this->shippingAddress->expects($this->once())->method('addData')->with($addressData); $this->shippingAddress->expects(static::once()) ->method('setCollectShippingRates') @@ -561,9 +593,9 @@ public function testEstimateByAddressId() $currencyCode = 'UAH'; /** - * @var \Magento\Customer\Api\Data\AddressInterface|MockObject $address + * @var AddressInterface|MockObject $address */ - $address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class) + $address = $this->getMockBuilder(AddressInterface::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Cart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/Cart.php index 34812c3eac410..fdfdc4b7280c2 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/Cart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/Cart.php @@ -43,7 +43,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $maskedCartId = $args['cart_id']; $currentUserId = $context->getUserId(); - $storeId = $storeId = (int)$context->getExtensionAttributes()->getStore()->getId(); + $storeId = (int)$context->getExtensionAttributes()->getStore()->getId(); $cart = $this->getCartForUser->execute($maskedCartId, $currentUserId, $storeId); return [ diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetBillingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetBillingAddressOnCart.php index c315aa9b14146..eb82510003fc7 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetBillingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetBillingAddressOnCart.php @@ -65,7 +65,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } $billingAddress = $args['input']['billing_address']; - $storeId = $storeId = (int)$context->getExtensionAttributes()->getStore()->getId(); + $storeId = (int)$context->getExtensionAttributes()->getStore()->getId(); $cart = $this->getCartForUser->execute($maskedCartId, $context->getUserId(), $storeId); $this->checkCartCheckoutAllowance->execute($cart); $this->setBillingAddressOnCart->execute($context, $cart, $billingAddress); diff --git a/app/code/Magento/ReleaseNotification/Ui/DataProvider/Modifier/Notifications.php b/app/code/Magento/ReleaseNotification/Ui/DataProvider/Modifier/Notifications.php index e82d61d499663..f42aedd9634b5 100644 --- a/app/code/Magento/ReleaseNotification/Ui/DataProvider/Modifier/Notifications.php +++ b/app/code/Magento/ReleaseNotification/Ui/DataProvider/Modifier/Notifications.php @@ -18,6 +18,8 @@ /** * Modifies the metadata returning to the Release Notification data provider + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class Notifications implements ModifierInterface { @@ -91,7 +93,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyData(array $data) { @@ -99,7 +101,7 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { @@ -149,6 +151,7 @@ private function buildNotificationMeta(array $meta, array $page, $isLastPage) 'actions' => [ [ 'targetName' => '${ $.name }', + '__disableTmpl' => ['targetName' => false], 'actionName' => 'closeReleaseNotes' ] ], @@ -232,6 +235,7 @@ private function unserializeContent($modalContent) /** * Returns the current Magento version used to retrieve the release notification content. + * * Version information after the dash (-) character is removed (ex. -dev or -rc). * * @return string diff --git a/app/code/Magento/Reports/Test/Mftf/Test/AdminReportsOrderedGroupedBySkuTest.xml b/app/code/Magento/Reports/Test/Mftf/Test/AdminReportsOrderedGroupedBySkuTest.xml index 6d0b335ac7094..650097214a0c4 100644 --- a/app/code/Magento/Reports/Test/Mftf/Test/AdminReportsOrderedGroupedBySkuTest.xml +++ b/app/code/Magento/Reports/Test/Mftf/Test/AdminReportsOrderedGroupedBySkuTest.xml @@ -28,8 +28,8 @@ <actionGroup ref="DeleteProductBySkuActionGroup" stepKey="deleteConfigurableProduct"> <argument name="sku" value="{{_defaultProduct.sku}}"/> </actionGroup> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteAttributeSet"> - <argument name="ProductAttribute" value="colorProductAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteAttributeSet"> + <argument name="productAttributeLabel" value="{{colorProductAttribute.default_label}}"/> </actionGroup> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> </after> diff --git a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php index 5f1401a201e3f..13f726f711219 100644 --- a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php +++ b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php @@ -85,10 +85,12 @@ public function modifyMeta(array $meta) 'behaviourType' => 'simple', 'externalFilterMode' => true, 'imports' => [ - 'productId' => '${ $.provider }:data.product.current_product_id' + 'productId' => '${ $.provider }:data.product.current_product_id', + '__disableTmpl' => ['productId' => false], ], 'exports' => [ - 'productId' => '${ $.externalProvider }:params.current_product_id' + 'productId' => '${ $.externalProvider }:params.current_product_id', + '__disableTmpl' => ['productId' => false], ], ], ], diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php index 3af058ef978cf..a7649fecaf2bb 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php @@ -6,6 +6,8 @@ namespace Magento\Sales\Block\Adminhtml\Order\Creditmemo\Create; use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\Sales\Model\Order; +use Zend_Currency; /** * Credit memo adjustments block @@ -68,6 +70,27 @@ public function initTotals() return $this; } + /** + * Format value based on order currency + * + * @param null|float $value + * + * @return string + */ + public function formatValue($value) + { + /** @var Order $order */ + $order = $this->getSource()->getOrder(); + + return $order->getOrderCurrency()->formatPrecision( + $value, + 2, + ['display' => Zend_Currency::NO_SYMBOL], + false, + false + ); + } + /** * Get source object * diff --git a/app/code/Magento/Sales/Block/Order/Email/Creditmemo/Items.php b/app/code/Magento/Sales/Block/Order/Email/Creditmemo/Items.php index 0b691eff5757b..0a1e87e5e0a27 100644 --- a/app/code/Magento/Sales/Block/Order/Email/Creditmemo/Items.php +++ b/app/code/Magento/Sales/Block/Order/Email/Creditmemo/Items.php @@ -5,6 +5,13 @@ */ namespace Magento\Sales\Block\Order\Email\Creditmemo; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\View\Element\Template\Context; +use Magento\Sales\Api\CreditmemoRepositoryInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\CreditmemoInterface; +use Magento\Sales\Api\OrderRepositoryInterface; + /** * Sales Order Email creditmemo items * @@ -14,6 +21,36 @@ */ class Items extends \Magento\Sales\Block\Items\AbstractItems { + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @var CreditmemoRepositoryInterface + */ + private $creditmemoRepository; + + /** + * @param Context $context + * @param array $data + * @param OrderRepositoryInterface|null $orderRepository + * @param CreditmemoRepositoryInterface|null $creditmemoRepository + */ + public function __construct( + Context $context, + array $data = [], + ?OrderRepositoryInterface $orderRepository = null, + ?CreditmemoRepositoryInterface $creditmemoRepository = null + ) { + $this->orderRepository = + $orderRepository ?: ObjectManager::getInstance()->get(OrderRepositoryInterface::class); + $this->creditmemoRepository = + $creditmemoRepository ?: ObjectManager::getInstance()->get(CreditmemoRepositoryInterface::class); + + parent::__construct($context, $data); + } + /** * Prepare item before output * @@ -25,4 +62,54 @@ protected function _prepareItem(\Magento\Framework\View\Element\AbstractBlock $r $renderer->getItem()->setOrder($this->getOrder()); $renderer->getItem()->setSource($this->getCreditmemo()); } + + /** + * Returns order. + * + * Custom email templates are only allowed to use scalar values for variable data. + * So order is loaded by order_id, that is passed to block from email template. + * For legacy custom email templates it can pass as an object. + * + * @return OrderInterface|null + */ + public function getOrder() + { + $order = $this->getData('order'); + if ($order !== null) { + return $order; + } + + $orderId = (int)$this->getData('order_id'); + if ($orderId) { + $order = $this->orderRepository->get($orderId); + $this->setData('order', $order); + } + + return $this->getData('order'); + } + + /** + * Returns creditmemo. + * + * Custom email templates are only allowed to use scalar values for variable data. + * So creditmemo is loaded by creditmemo_id, that is passed to block from email template. + * For legacy custom email templates it can pass as an object. + * + * @return CreditmemoInterface|null + */ + public function getCreditmemo() + { + $creditmemo = $this->getData('creditmemo'); + if ($creditmemo !== null) { + return $creditmemo; + } + + $creditmemoId = (int)$this->getData('creditmemo_id'); + if ($creditmemoId) { + $creditmemo = $this->creditmemoRepository->get($creditmemoId); + $this->setData('creditmemo', $creditmemo); + } + + return $this->getData('creditmemo'); + } } diff --git a/app/code/Magento/Sales/Block/Order/Email/Invoice/Items.php b/app/code/Magento/Sales/Block/Order/Email/Invoice/Items.php index bc7756816d32a..cc2b197ab0eb2 100644 --- a/app/code/Magento/Sales/Block/Order/Email/Invoice/Items.php +++ b/app/code/Magento/Sales/Block/Order/Email/Invoice/Items.php @@ -6,6 +6,13 @@ namespace Magento\Sales\Block\Order\Email\Invoice; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\View\Element\Template\Context; +use Magento\Sales\Api\Data\InvoiceInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\InvoiceRepositoryInterface; +use Magento\Sales\Api\OrderRepositoryInterface; + /** * Sales Order Email Invoice items * @@ -14,6 +21,36 @@ */ class Items extends \Magento\Sales\Block\Items\AbstractItems { + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @var InvoiceRepositoryInterface + */ + private $invoiceRepository; + + /** + * @param Context $context + * @param array $data + * @param OrderRepositoryInterface|null $orderRepository + * @param InvoiceRepositoryInterface|null $invoiceRepository + */ + public function __construct( + Context $context, + array $data = [], + ?OrderRepositoryInterface $orderRepository = null, + ?InvoiceRepositoryInterface $invoiceRepository = null + ) { + $this->orderRepository = + $orderRepository ?: ObjectManager::getInstance()->get(OrderRepositoryInterface::class); + $this->invoiceRepository = + $invoiceRepository ?: ObjectManager::getInstance()->get(InvoiceRepositoryInterface::class); + + parent::__construct($context, $data); + } + /** * Prepare item before output * @@ -25,4 +62,54 @@ protected function _prepareItem(\Magento\Framework\View\Element\AbstractBlock $r $renderer->getItem()->setOrder($this->getOrder()); $renderer->getItem()->setSource($this->getInvoice()); } + + /** + * Returns order. + * + * Custom email templates are only allowed to use scalar values for variable data. + * So order is loaded by order_id, that is passed to block from email template. + * For legacy custom email templates it can pass as an object. + * + * @return OrderInterface|null + */ + public function getOrder() + { + $order = $this->getData('order'); + if ($order !== null) { + return $order; + } + + $orderId = (int)$this->getData('order_id'); + if ($orderId) { + $order = $this->orderRepository->get($orderId); + $this->setData('order', $order); + } + + return $this->getData('order'); + } + + /** + * Returns invoice. + * + * Custom email templates are only allowed to use scalar values for variable data. + * So invoice is loaded by invoice_id, that is passed to block from email template. + * For legacy custom email templates it can pass as an object. + * + * @return InvoiceInterface|null + */ + public function getInvoice() + { + $invoice = $this->getData('invoice'); + if ($invoice !== null) { + return $invoice; + } + + $invoiceId = (int)$this->getData('invoice_id'); + if ($invoiceId) { + $invoice = $this->invoiceRepository->get($invoiceId); + $this->setData('invoice', $invoice); + } + + return $this->getData('invoice'); + } } diff --git a/app/code/Magento/Sales/Block/Order/Email/Items.php b/app/code/Magento/Sales/Block/Order/Email/Items.php index ddce387b91068..e11981285f04f 100644 --- a/app/code/Magento/Sales/Block/Order/Email/Items.php +++ b/app/code/Magento/Sales/Block/Order/Email/Items.php @@ -11,10 +11,61 @@ */ namespace Magento\Sales\Block\Order\Email; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\View\Element\Template\Context; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\OrderRepositoryInterface; + /** + * Sales Order Email items. + * * @api * @since 100.0.2 */ class Items extends \Magento\Sales\Block\Items\AbstractItems { + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @param Context $context + * @param array $data + * @param OrderRepositoryInterface|null $orderRepository + */ + public function __construct( + Context $context, + array $data = [], + ?OrderRepositoryInterface $orderRepository = null + ) { + $this->orderRepository = $orderRepository ?: ObjectManager::getInstance()->get(OrderRepositoryInterface::class); + + parent::__construct($context, $data); + } + + /** + * Returns order. + * + * Custom email templates are only allowed to use scalar values for variable data. + * So order is loaded by order_id, that is passed to block from email template. + * For legacy custom email templates it can pass as an object. + * + * @return OrderInterface|null + */ + public function getOrder() + { + $order = $this->getData('order'); + + if ($order !== null) { + return $order; + } + $orderId = (int)$this->getData('order_id'); + if ($orderId) { + $order = $this->orderRepository->get($orderId); + $this->setData('order', $order); + } + + return $this->getData('order'); + } } diff --git a/app/code/Magento/Sales/Block/Order/Email/Shipment/Items.php b/app/code/Magento/Sales/Block/Order/Email/Shipment/Items.php index a4c9a7b80a00d..1f9b353180fd9 100644 --- a/app/code/Magento/Sales/Block/Order/Email/Shipment/Items.php +++ b/app/code/Magento/Sales/Block/Order/Email/Shipment/Items.php @@ -6,6 +6,13 @@ namespace Magento\Sales\Block\Order\Email\Shipment; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\View\Element\Template\Context; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Api\ShipmentRepositoryInterface; + /** * Sales Order Email Shipment items * @@ -14,6 +21,36 @@ */ class Items extends \Magento\Sales\Block\Items\AbstractItems { + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @var ShipmentRepositoryInterface + */ + private $shipmentRepository; + + /** + * @param Context $context + * @param array $data + * @param OrderRepositoryInterface|null $orderRepository + * @param ShipmentRepositoryInterface|null $creditmemoRepository + */ + public function __construct( + Context $context, + array $data = [], + ?OrderRepositoryInterface $orderRepository = null, + ?ShipmentRepositoryInterface $creditmemoRepository = null + ) { + $this->orderRepository = + $orderRepository ?: ObjectManager::getInstance()->get(OrderRepositoryInterface::class); + $this->shipmentRepository = + $creditmemoRepository ?: ObjectManager::getInstance()->get(ShipmentRepositoryInterface::class); + + parent::__construct($context, $data); + } + /** * Prepare item before output * @@ -25,4 +62,54 @@ protected function _prepareItem(\Magento\Framework\View\Element\AbstractBlock $r $renderer->getItem()->setOrder($this->getOrder()); $renderer->getItem()->setSource($this->getShipment()); } + + /** + * Returns order. + * + * Custom email templates are only allowed to use scalar values for variable data. + * So order is loaded by order_id, that is passed to block from email template. + * For legacy custom email templates it can pass as an object. + * + * @return OrderInterface|null + */ + public function getOrder() + { + $order = $this->getData('order'); + if ($order !== null) { + return $order; + } + + $orderId = (int)$this->getData('order_id'); + if ($orderId) { + $order = $this->orderRepository->get($orderId); + $this->setData('order', $order); + } + + return $this->getData('order'); + } + + /** + * Returns shipment. + * + * Custom email templates are only allowed to use scalar values for variable data. + * So shipment is loaded by shipment_id, that is passed to block from email template. + * For legacy custom email templates it can pass as an object. + * + * @return ShipmentInterface|null + */ + public function getShipment() + { + $shipment = $this->getData('shipment'); + if ($shipment !== null) { + return $shipment; + } + + $shipmentId = (int)$this->getData('shipment_id'); + if ($shipmentId) { + $shipment = $this->shipmentRepository->get($shipmentId); + $this->setData('shipment', $shipment); + } + + return $this->getData('shipment'); + } } diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php index 93c8305ec2396..57cd21ffa9eb1 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php @@ -8,7 +8,6 @@ namespace Magento\Sales\Controller\Adminhtml\Order; -use Magento\Backend\App\Action; use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; /** @@ -63,17 +62,20 @@ public function execute() } $this->orderRepository->save($order); $this->messageManager->addSuccessMessage($message); - $resultRedirect->setPath('sales/order/view', ['order_id' => $order->getEntityId()]); - } else { - $resultRedirect->setPath('sales/*/'); - return $resultRedirect; } // phpcs:ignore Magento2.Exceptions.ThrowCatch } catch (\Magento\Framework\Exception\LocalizedException $e) { + $this->messageManager->addErrorMessage($e->getMessage()); $this->messageManager->addErrorMessage(__('We can\'t update the payment right now.')); $this->logger->critical($e); + } + + if ($order) { + $resultRedirect->setPath('sales/order/view', ['order_id' => $order->getEntityId()]); + } else { $resultRedirect->setPath('sales/*/'); } + return $resultRedirect; } } diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php b/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php index 73afd0a06f710..8138e193e7978 100644 --- a/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php +++ b/app/code/Magento/Sales/Model/Order/CreditmemoFactory.php @@ -6,10 +6,15 @@ namespace Magento\Sales\Model\Order; use Magento\Bundle\Ui\DataProvider\Product\Listing\Collector\BundlePrice; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Locale\FormatInterface; +use Magento\Framework\Serialize\Serializer\Json as JsonSerializer; use Magento\Sales\Api\Data\OrderItemInterface; /** * Factory class for @see \Magento\Sales\Model\Order\Creditmemo + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class CreditmemoFactory { @@ -32,7 +37,12 @@ class CreditmemoFactory protected $unserialize; /** - * @var \Magento\Framework\Serialize\Serializer\Json + * @var FormatInterface + */ + private $localeFormat; + + /** + * @var JsonSerializer */ private $serializer; @@ -41,18 +51,19 @@ class CreditmemoFactory * * @param \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory * @param \Magento\Tax\Model\Config $taxConfig - * @param \Magento\Framework\Serialize\Serializer\Json $serializer + * @param JsonSerializer $serializer + * @param FormatInterface $localeFormat */ public function __construct( \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory, \Magento\Tax\Model\Config $taxConfig, - \Magento\Framework\Serialize\Serializer\Json $serializer = null + JsonSerializer $serializer = null, + FormatInterface $localeFormat = null ) { $this->convertor = $convertOrderFactory->create(); $this->taxConfig = $taxConfig; - $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\Serialize\Serializer\Json::class - ); + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(JsonSerializer::class); + $this->localeFormat = $localeFormat ?: ObjectManager::getInstance()->get(FormatInterface::class); } /** @@ -166,6 +177,7 @@ protected function canRefundItem($item, $qtys = [], $invoiceQtysRefundLimits = [ return isset($qtys[$parent->getId()]) && $qtys[$parent->getId()] > 0; } } + return false; } else { return $this->canRefundNoDummyItem($item, $invoiceQtysRefundLimits); } @@ -199,14 +211,17 @@ protected function canRefundNoDummyItem($item, $invoiceQtysRefundLimits = []) protected function initData($creditmemo, $data) { if (isset($data['shipping_amount'])) { - $creditmemo->setBaseShippingAmount((double)$data['shipping_amount']); - $creditmemo->setBaseShippingInclTax((double)$data['shipping_amount']); + $shippingAmount = $this->parseNumber($data['shipping_amount']); + $creditmemo->setBaseShippingAmount($shippingAmount); + $creditmemo->setBaseShippingInclTax($shippingAmount); } if (isset($data['adjustment_positive'])) { - $creditmemo->setAdjustmentPositive($data['adjustment_positive']); + $adjustmentPositiveAmount = $this->parseAdjustmentAmount($data['adjustment_positive']); + $creditmemo->setAdjustmentPositive($adjustmentPositiveAmount); } if (isset($data['adjustment_negative'])) { - $creditmemo->setAdjustmentNegative($data['adjustment_negative']); + $adjustmentNegativeAmount = $this->parseAdjustmentAmount($data['adjustment_negative']); + $creditmemo->setAdjustmentNegative($adjustmentNegativeAmount); } } @@ -340,4 +355,32 @@ private function getShippingAmount(Invoice $invoice): float return (float)$amount; } + + /** + * Parse adjustment amount value to number + * + * @param string|null $amount + * + * @return float|null + */ + private function parseAdjustmentAmount($amount) + { + $amount = trim($amount); + $percentAmount = substr($amount, -1) == '%'; + $amount = $this->parseNumber($amount); + + return $percentAmount ? $amount . '%' : $amount; + } + + /** + * Parse value to number + * + * @param string|null $value + * + * @return float|null + */ + private function parseNumber($value) + { + return $this->localeFormat->getNumber($value); + } } diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php index e6d528fb93a34..c27afe9fb5b0d 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/CreditmemoSender.php @@ -17,7 +17,7 @@ use Magento\Framework\DataObject; /** - * Class CreditmemoSender + * Sends order creditmemo email to the customer. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -108,7 +108,9 @@ public function send(Creditmemo $creditmemo, $forceSyncMode = false) $transport = [ 'order' => $order, + 'order_id' => $order->getId(), 'creditmemo' => $creditmemo, + 'creditmemo_id' => $creditmemo->getId(), 'comment' => $creditmemo->getCustomerNoteNotify() ? $creditmemo->getCustomerNote() : '', 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php index 79133af6d6fb8..05164d1b7b5f3 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php @@ -17,7 +17,7 @@ use Magento\Framework\DataObject; /** - * Class InvoiceSender + * Sends order invoice email to the customer. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -108,7 +108,9 @@ public function send(Invoice $invoice, $forceSyncMode = false) $transport = [ 'order' => $order, + 'order_id' => $order->getId(), 'invoice' => $invoice, + 'invoice_id' => $invoice->getId(), 'comment' => $invoice->getCustomerNoteNotify() ? $invoice->getCustomerNote() : '', 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php index c67804475cd65..a2d61c3b2d31d 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/OrderSender.php @@ -16,7 +16,8 @@ use Magento\Framework\DataObject; /** - * Class OrderSender + * Sends order email to the customer. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class OrderSender extends Sender @@ -125,6 +126,7 @@ protected function prepareTemplate(Order $order) { $transport = [ 'order' => $order, + 'order_id' => $order->getId(), 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), 'store' => $order->getStore(), diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php index c6b40800d5160..4c8e1744ac0e0 100644 --- a/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php +++ b/app/code/Magento/Sales/Model/Order/Email/Sender/ShipmentSender.php @@ -17,7 +17,7 @@ use Magento\Framework\DataObject; /** - * Class for shipment email notification sender + * Sends order shipment email to the customer. * * @deprecated since this class works only with the concrete model and no data interface * @see \Magento\Sales\Model\Order\Shipment\Sender\EmailSender @@ -110,7 +110,9 @@ public function send(Shipment $shipment, $forceSyncMode = false) $transport = [ 'order' => $order, + 'order_id' => $order->getId(), 'shipment' => $shipment, + 'shipment_id' => $shipment->getId(), 'comment' => $shipment->getCustomerNoteNotify() ? $shipment->getCustomerNote() : '', 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php b/app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php index 1d4418c50047d..fe68555d9f7c7 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php @@ -104,7 +104,9 @@ public function send( $transport = [ 'order' => $order, + 'order_id' => $order->getId(), 'shipment' => $shipment, + 'shipment_id' => $shipment->getId(), 'comment' => $comment ? $comment->getComment() : '', 'billing' => $order->getBillingAddress(), 'payment_html' => $this->getPaymentHtml($order), diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderGridClickFirstRowActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderGridClickFirstRowActionGroup.xml new file mode 100644 index 0000000000000..92b67af7d7f5a --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderGridClickFirstRowActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminOrderGridClickFirstRowActionGroup"> + <annotations> + <description>Click on first row of Order Grid.</description> + </annotations> + + <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickFirstOrderRow"/> + <waitForPageLoad stepKey="waitForOrderPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminCreditMemoNewPageTotalsActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminCreditMemoNewPageTotalsActionGroup.xml new file mode 100644 index 0000000000000..8465383e0c40c --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminCreditMemoNewPageTotalsActionGroup.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertAdminCreditMemoNewPageTotalsActionGroup"> + <annotations> + <description>Checks totals values on the Credit Memo new page.</description> + </annotations> + <arguments> + <argument name="refundShipping" type="string" defaultValue="0"/> + <argument name="adjustmentRefund" type="string" defaultValue="0"/> + <argument name="adjustmentFee" type="string" defaultValue="0"/> + <argument name="grandTotal" type="string" defaultValue="0"/> + </arguments> + + <seeInField selector="{{AdminCreditMemoTotalSection.refundShipping}}" userInput="{{refundShipping}}" stepKey="seeRefundShipping"/> + <seeInField selector="{{AdminCreditMemoTotalSection.adjustmentRefund}}" userInput="{{adjustmentRefund}}" stepKey="seeAdjustmentRefund"/> + <seeInField selector="{{AdminCreditMemoTotalSection.adjustmentFee}}" userInput="{{adjustmentFee}}" stepKey="seeAdjustmentFee"/> + <see selector="{{AdminCreditMemoTotalSection.grandTotal}}" userInput="{{grandTotal}}" stepKey="seeGrandTotal"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminCreditMemoViewPageTotalsActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminCreditMemoViewPageTotalsActionGroup.xml new file mode 100644 index 0000000000000..7bea25a6c5252 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertAdminCreditMemoViewPageTotalsActionGroup.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertAdminCreditMemoViewPageTotalsActionGroup"> + <annotations> + <description>Checks totals values on the Credit Memo view page.</description> + </annotations> + <arguments> + <argument name="subtotal" type="string" defaultValue="0"/> + <argument name="adjustmentRefund" type="string" defaultValue="0"/> + <argument name="adjustmentFee" type="string" defaultValue="0"/> + <argument name="grandTotal" type="string" defaultValue="0"/> + </arguments> + + <see selector="{{AdminCreditMemoViewTotalSection.subtotal}}" userInput="{{subtotal}}" stepKey="seeSubtotal"/> + <see selector="{{AdminCreditMemoViewTotalSection.adjustmentRefund}}" userInput="{{adjustmentRefund}}" stepKey="seeAdjustmentRefund"/> + <see selector="{{AdminCreditMemoViewTotalSection.adjustmentFee}}" userInput="{{adjustmentFee}}" stepKey="seeAdjustmentFee"/> + <see selector="{{AdminCreditMemoViewTotalSection.grandTotal}}" userInput="{{grandTotal}}" stepKey="seeGrandTotal"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/OrderSelectFlatRateShippingActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/OrderSelectFlatRateShippingActionGroup.xml index b85dc21e0b1b5..aca3ee0fdfef6 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/OrderSelectFlatRateShippingActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/OrderSelectFlatRateShippingActionGroup.xml @@ -14,7 +14,7 @@ </annotations> <click selector="{{AdminOrderFormPaymentSection.header}}" stepKey="unfocus"/> - <waitForPageLoad stepKey="waitForJavascriptToFinish"/> + <waitForLoadingMaskToDisappear stepKey="waitForJavascriptToFinish"/> <click selector="{{AdminOrderFormPaymentSection.getShippingMethods}}" stepKey="clickShippingMethods"/> <waitForElementVisible selector="{{AdminOrderFormPaymentSection.flatRateOption}}" stepKey="waitForShippingOptions"/> <selectOption selector="{{AdminOrderFormPaymentSection.flatRateOption}}" userInput="flatrate_flatrate" stepKey="checkFlatRate"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckNewCreditMemoTotalsForFranceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckNewCreditMemoTotalsForFranceTest.xml new file mode 100644 index 0000000000000..ce6848c3e9d66 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckNewCreditMemoTotalsForFranceTest.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckNewCreditMemoTotalsForFranceTest" extends="AdminCreateCreditMemoWithCashOnDeliveryTest"> + <annotations> + <stories value="Credit memo entity for France locale"/> + <title value="Credit memo entity for France locale"/> + <description value="Create Credit Memo with cash on delivery payment and assert 0 shipping refund for France locale"/> + <group value="sales"/> + </annotations> + <before> + <magentoCLI command="setup:static-content:deploy fr_FR" stepKey="deployStaticContentWithFrenchLocale" before="LoginAsAdmin"/> + <actionGroup ref="SetAdminAccountActionGroup" stepKey="setAdminInterfaceLocaleToFrance" after="LoginAsAdmin"> + <argument name="InterfaceLocaleByValue" value="fr_FR"/> + </actionGroup> + </before> + <after> + <actionGroup ref="SetAdminAccountActionGroup" stepKey="setAdminInterfaceLocaleToDefaultValue" before="logout"> + <argument name="InterfaceLocaleByValue" value="en_US"/> + </actionGroup> + </after> + + <actionGroup ref="AdminOpenAndFillCreditMemoRefundActionGroup" stepKey="fillCreditMemoRefund"> + <argument name="itemQtyToRefund" value="1"/> + <argument name="shippingRefund" value="0"/> + <argument name="adjustmentRefund" value="5,31"/> + <argument name="adjustmentFee" value="10,31"/> + </actionGroup> + + <actionGroup ref="AssertAdminCreditMemoNewPageTotalsActionGroup" stepKey="assertCreditMemoRefundTotals" after="fillCreditMemoRefund"> + <argument name="refundShipping" value="0,00"/> + <argument name="adjustmentRefund" value="5,31"/> + <argument name="adjustmentFee" value="10,31"/> + <argument name="subtotalRow" value="560,00"/> + <argument name="grandTotal" value="555,00"/> + </actionGroup> + + <actionGroup ref="AssertAdminCreditMemoViewPageTotalsActionGroup" stepKey="assertCreditMemoViewPageTotals"> + <argument name="subtotal" value="560,00"/> + <argument name="adjustmentRefund" value="5,31"/> + <argument name="adjustmentFee" value="10,31"/> + <argument name="grandTotal" value="555,00"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml index 69e3ade9231d0..b8612f7f795fb 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml @@ -81,8 +81,7 @@ <actionGroup ref="FilterOrderGridByIdActionGroup" stepKey="filterOrderGridById"> <argument name="orderId" value="$grabOrderNumber"/> </actionGroup> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForCreatedOrderPageOpened"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <actionGroup ref="GoToInvoiceIntoOrderActionGroup" stepKey="goToInvoiceIntoOrderPage"/> <fillField selector="{{AdminInvoiceItemsSection.qtyToInvoiceColumn}}" userInput="5" stepKey="ChangeQtyToInvoice"/> <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQuantity"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml index 45eefbcc3f97d..d888e6841e34d 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateCreditMemoWithCashOnDeliveryTest.xml @@ -102,10 +102,12 @@ <click selector="{{AdminCreditMemosGridSection.memoId}}" stepKey="clickView"/> <waitForPageLoad stepKey="waitForCreditMemo"/> <scrollTo selector="{{AdminCreditMemoViewTotalSection.subtotal}}" stepKey="scrollToTotal"/> - <see selector="{{AdminCreditMemoViewTotalSection.subtotal}}" userInput="$560.00" stepKey="seeSubtotal"/> - <see selector="{{AdminCreditMemoViewTotalSection.adjustmentRefund}}" userInput="$5.00" stepKey="seeAdjustmentRefund"/> - <see selector="{{AdminCreditMemoViewTotalSection.adjustmentFee}}" userInput="$10.00" stepKey="seeAdjustmentFee"/> - <see selector="{{AdminCreditMemoViewTotalSection.grandTotal}}" userInput="$555.00" stepKey="assertRefundOnCreditMemoTab"/> + <actionGroup ref="AssertAdminCreditMemoViewPageTotalsActionGroup" stepKey="assertCreditMemoViewPageTotals"> + <argument name="subtotal" value="$560.00"/> + <argument name="adjustmentRefund" value="$5.00"/> + <argument name="adjustmentFee" value="$10.00"/> + <argument name="grandTotal" value="$555.00"/> + </actionGroup> <!--Login to storefront as previously created customer--> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index 1411f7b292757..eea948d902282 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -36,7 +36,7 @@ <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> <click selector="{{StorefrontCategoryMainSection.AddToCartBtn}}" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductAdded"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForPageLoad2"/> <fillField selector="{{CheckoutShippingGuestInfoSection.email}}" userInput="{{CustomerEntityOne.email}}" stepKey="enterEmail"/> @@ -68,8 +68,7 @@ <click selector="{{AdminOrdersGridSection.submitSearch}}" stepKey="submitSearch"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoice"/> <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index 09197963434eb..bd76f5c10b488 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -66,7 +66,7 @@ <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverOverProduct"/> <click selector="{{StorefrontCategoryMainSection.AddToCartBtn}}" stepKey="addToCart"/> <waitForElementVisible selector="{{StorefrontCategoryMainSection.SuccessMsg}}" time="30" stepKey="waitForProductToAdd"/> - <click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/> + <actionGroup ref="StorefrontClickOnMiniCartActionGroup" stepKey="clickCart"/> <click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout"/> <waitForPageLoad stepKey="waitForPageLoad2"/> <!-- fill out customer information --> @@ -103,8 +103,7 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask4"/> <!-- Create invoice --> - <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> - <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + <actionGroup ref="AdminOrderGridClickFirstRowActionGroup" stepKey="clickOrderRow"/> <click selector="{{AdminOrderDetailsMainActionsSection.invoice}}" stepKey="clickInvoiceButton"/> <waitForPageLoad stepKey="waitForNewInvoicePageToLoad"/> <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoiceInPageTitle" after="clickInvoiceButton"/> diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php index 2f4e0e927db2c..39c85b955d9b5 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/AbstractSenderTest.php @@ -5,6 +5,22 @@ */ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; +use Magento\Framework\App\Config; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Event\Manager; +use Magento\Payment\Helper\Data; +use Magento\Payment\Model\Info; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Sales\Model\Order\Email\Container\Template; +use Magento\Sales\Model\Order\Email\Sender; +use Magento\Sales\Model\Order\Email\SenderBuilderFactory; +use Magento\Store\Model\Store; +use PHPUnit\Framework\MockObject\Matcher\InvokedCount; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; + /** * Class AbstractSenderTest * @@ -13,89 +29,89 @@ abstract class AbstractSenderTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Sales\Model\Order\Email\Sender|\PHPUnit_Framework_MockObject_MockObject + * @var Sender|MockObject */ protected $senderMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $senderBuilderFactoryMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $templateContainerMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $identityContainerMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $storeMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $orderMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $paymentHelper; /** - * @var \Magento\Sales\Model\Order\Address\Renderer|\PHPUnit_Framework_MockObject_MockObject + * @var Renderer|MockObject */ protected $addressRenderer; /** * Global configuration storage mock. * - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ protected $globalConfig; /** - * @var \Magento\Sales\Model\Order\Address|\PHPUnit_Framework_MockObject_MockObject + * @var Address|MockObject */ protected $addressMock; /** - * @var \Magento\Framework\Event\Manager | \PHPUnit_Framework_MockObject_MockObject + * @var Manager|MockObject */ protected $eventManagerMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ protected $loggerMock; public function stepMockSetup() { $this->senderMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Email\Sender::class, + Sender::class, ['send', 'sendCopyTo'] ); $this->senderBuilderFactoryMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Email\SenderBuilderFactory::class, + SenderBuilderFactory::class, ['create'] ); $this->templateContainerMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Email\Container\Template::class, + Template::class, ['setTemplateVars'] ); - $this->storeMock = $this->createPartialMock(\Magento\Store\Model\Store::class, ['getStoreId', '__wakeup']); + $this->storeMock = $this->createPartialMock(Store::class, ['getStoreId', '__wakeup']); $this->orderMock = $this->createPartialMock( - \Magento\Sales\Model\Order::class, + Order::class, [ - 'getStore', 'getBillingAddress', 'getPayment', + 'getId', 'getStore', 'getBillingAddress', 'getPayment', '__wakeup', 'getCustomerIsGuest', 'getCustomerName', 'getCustomerEmail', 'getShippingAddress', 'setSendEmail', 'setEmailSent', 'getCreatedAtFormatted', 'getIsNotVirtual', @@ -105,23 +121,23 @@ public function stepMockSetup() $this->orderMock->expects($this->any()) ->method('getStore') ->will($this->returnValue($this->storeMock)); - $paymentInfoMock = $this->createMock(\Magento\Payment\Model\Info::class); + $paymentInfoMock = $this->createMock(Info::class); $this->orderMock->expects($this->any()) ->method('getPayment') ->will($this->returnValue($paymentInfoMock)); - $this->addressRenderer = $this->createMock(\Magento\Sales\Model\Order\Address\Renderer::class); - $this->addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); - $this->eventManagerMock = $this->createMock(\Magento\Framework\Event\Manager::class); + $this->addressRenderer = $this->createMock(Renderer::class); + $this->addressMock = $this->createMock(Address::class); + $this->eventManagerMock = $this->createMock(Manager::class); - $this->paymentHelper = $this->createPartialMock(\Magento\Payment\Helper\Data::class, ['getInfoBlockHtml']); + $this->paymentHelper = $this->createPartialMock(Data::class, ['getInfoBlockHtml']); $this->paymentHelper->expects($this->any()) ->method('getInfoBlockHtml') ->will($this->returnValue('payment')); - $this->globalConfig = $this->createPartialMock(\Magento\Framework\App\Config::class, ['getValue']); + $this->globalConfig = $this->createPartialMock(Config::class, ['getValue']); - $this->loggerMock = $this->createMock(\Psr\Log\LoggerInterface::class); + $this->loggerMock = $this->createMock(LoggerInterface::class); } /** @@ -168,14 +184,14 @@ public function stepIdentityContainerInit($identityMockClassName) } /** - * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $sendExpects - * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $sendCopyToExpects + * @param InvokedCount $sendExpects + * @param InvokedCount $sendCopyToExpects */ protected function stepSend( - \PHPUnit\Framework\MockObject\Matcher\InvokedCount $sendExpects, - \PHPUnit\Framework\MockObject\Matcher\InvokedCount $sendCopyToExpects + InvokedCount $sendExpects, + InvokedCount $sendCopyToExpects ) { - $senderMock = $this->createPartialMock(\Magento\Sales\Model\Order\Email\Sender::class, ['send', 'sendCopyTo']); + $senderMock = $this->createPartialMock(Sender::class, ['send', 'sendCopyTo']); $senderMock->expects($sendExpects) ->method('send'); $senderMock->expects($sendCopyToExpects) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php index 72a51a15db592..6bcabea7df202 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/CreditmemoSenderTest.php @@ -5,25 +5,36 @@ */ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\Order\Creditmemo; +use Magento\Sales\Model\ResourceModel\Order\Creditmemo as CreditmemoResource; +use Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity; use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender; +use Magento\Sales\Model\ResourceModel\EntityAbstract; +use PHPUnit\Framework\MockObject\MockObject; /** * Test for Magento\Sales\Model\Order\Email\Sender\CreditmemoSender class. */ class CreditmemoSenderTest extends AbstractSenderTest { + private const CREDITMEMO_ID = 1; + + private const ORDER_ID = 1; + /** - * @var \Magento\Sales\Model\Order\Email\Sender\CreditmemoSender + * @var CreditmemoSender */ protected $sender; /** - * @var \Magento\Sales\Model\Order\Creditmemo|\PHPUnit_Framework_MockObject_MockObject + * @var Creditmemo|MockObject */ protected $creditmemoMock; /** - * @var \Magento\Sales\Model\ResourceModel\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject + * @var EntityAbstract|MockObject */ protected $creditmemoResourceMock; @@ -32,14 +43,15 @@ protected function setUp() $this->stepMockSetup(); $this->creditmemoResourceMock = $this->createPartialMock( - \Magento\Sales\Model\ResourceModel\Order\Creditmemo::class, + CreditmemoResource::class, ['saveAttribute'] ); $this->creditmemoMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Creditmemo::class, + Creditmemo::class, [ 'getStore', + 'getId', '__wakeup', 'getOrder', 'setSendEmail', @@ -54,9 +66,13 @@ protected function setUp() $this->creditmemoMock->expects($this->any()) ->method('getOrder') ->will($this->returnValue($this->orderMock)); + $this->creditmemoMock->method('getId') + ->willReturn(self::CREDITMEMO_ID); + $this->orderMock->method('getId') + ->willReturn(self::ORDER_ID); $this->identityContainerMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Email\Container\CreditmemoIdentity::class, + CreditmemoIdentity::class, ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId', 'getCopyMethod'] ); $this->identityContainerMock->expects($this->any()) @@ -104,7 +120,7 @@ public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $ema ->willReturn($configValue); if (!$configValue || $forceSyncMode) { - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->exactly(2)) ->method('format') @@ -142,7 +158,9 @@ public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $ema ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'creditmemo' => $this->creditmemoMock, + 'creditmemo_id' => self::CREDITMEMO_ID, 'comment' => $customerNoteNotify ? $comment : '', 'billing' => $addressMock, 'payment_html' => 'payment', @@ -240,7 +258,7 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte $frontendStatusLabel = 'Complete'; $isNotVirtual = false; - $this->orderMock->setData(\Magento\Sales\Api\Data\OrderInterface::IS_VIRTUAL, $isVirtualOrder); + $this->orderMock->setData(OrderInterface::IS_VIRTUAL, $isVirtualOrder); $this->orderMock->expects($this->any()) ->method('getCustomerName') @@ -267,7 +285,7 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with('sales_email/general/async_sending') ->willReturn(false); - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->exactly($formatCallCount)) ->method('format') @@ -285,7 +303,9 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'creditmemo' => $this->creditmemoMock, + 'creditmemo_id' => self::CREDITMEMO_ID, 'comment' => '', 'billing' => $addressMock, 'payment_html' => 'payment', diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php index 00a1855055a84..206db7b9c7e0b 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/InvoiceSenderTest.php @@ -5,25 +5,36 @@ */ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\Order\Email\Container\InvoiceIdentity; use Magento\Sales\Model\Order\Email\Sender\InvoiceSender; +use Magento\Sales\Model\Order\Invoice; +use Magento\Sales\Model\ResourceModel\Order\Invoice as InvoiceResource; +use Magento\Sales\Model\ResourceModel\EntityAbstract; +use PHPUnit\Framework\MockObject\MockObject; /** * Test for Magento\Sales\Model\Order\Email\Sender\InvoiceSender class. */ class InvoiceSenderTest extends AbstractSenderTest { + private const INVOICE_ID = 1; + + private const ORDER_ID = 1; + /** - * @var \Magento\Sales\Model\Order\Email\Sender\InvoiceSender + * @var InvoiceSender */ protected $sender; /** - * @var \Magento\Sales\Model\Order\Invoice|\PHPUnit_Framework_MockObject_MockObject + * @var Invoice|MockObject */ protected $invoiceMock; /** - * @var \Magento\Sales\Model\ResourceModel\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject + * @var EntityAbstract|MockObject */ protected $invoiceResourceMock; @@ -32,14 +43,15 @@ protected function setUp() $this->stepMockSetup(); $this->invoiceResourceMock = $this->createPartialMock( - \Magento\Sales\Model\ResourceModel\Order\Invoice::class, + InvoiceResource::class, ['saveAttribute'] ); $this->invoiceMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Invoice::class, + Invoice::class, [ 'getStore', + 'getId', '__wakeup', 'getOrder', 'setSendEmail', @@ -55,8 +67,13 @@ protected function setUp() ->method('getOrder') ->will($this->returnValue($this->orderMock)); + $this->invoiceMock->method('getId') + ->willReturn(self::INVOICE_ID); + $this->orderMock->method('getId') + ->willReturn(self::ORDER_ID); + $this->identityContainerMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Email\Container\InvoiceIdentity::class, + InvoiceIdentity::class, ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId', 'getCopyMethod'] ); $this->identityContainerMock->expects($this->any()) @@ -104,7 +121,7 @@ public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $ema ->willReturn($configValue); if (!$configValue || $forceSyncMode) { - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->any()) ->method('format') @@ -148,7 +165,9 @@ public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $ema ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'invoice' => $this->invoiceMock, + 'invoice_id' => self::INVOICE_ID, 'comment' => $customerNoteNotify ? $comment : '', 'billing' => $addressMock, 'payment_html' => 'payment', @@ -240,7 +259,7 @@ public function sendDataProvider() public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expectedShippingAddress) { $billingAddress = 'address_test'; - $this->orderMock->setData(\Magento\Sales\Api\Data\OrderInterface::IS_VIRTUAL, $isVirtualOrder); + $this->orderMock->setData(OrderInterface::IS_VIRTUAL, $isVirtualOrder); $customerName = 'Test Customer'; $frontendStatusLabel = 'Complete'; $isNotVirtual = false; @@ -254,7 +273,7 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with('sales_email/general/async_sending') ->willReturn(false); - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->exactly($formatCallCount)) ->method('format') @@ -287,7 +306,9 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'invoice' => $this->invoiceMock, + 'invoice_id' => self::INVOICE_ID, 'comment' => '', 'billing' => $addressMock, 'payment_html' => 'payment', diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php index a033e41dd8e8b..7d5cb7028ddc3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/OrderSenderTest.php @@ -5,17 +5,25 @@ */ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\Order\Email\Container\OrderIdentity; use Magento\Sales\Model\Order\Email\Sender\OrderSender; +use Magento\Sales\Model\ResourceModel\EntityAbstract; +use Magento\Sales\Model\ResourceModel\Order; +use PHPUnit\Framework\MockObject\MockObject; class OrderSenderTest extends AbstractSenderTest { + private const ORDER_ID = 1; + /** - * @var \Magento\Sales\Model\Order\Email\Sender\OrderSender + * @var OrderSender */ protected $sender; /** - * @var \Magento\Sales\Model\ResourceModel\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject + * @var EntityAbstract|MockObject */ protected $orderResourceMock; @@ -24,18 +32,21 @@ protected function setUp() $this->stepMockSetup(); $this->orderResourceMock = $this->createPartialMock( - \Magento\Sales\Model\ResourceModel\Order::class, + Order::class, ['saveAttribute'] ); $this->identityContainerMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Email\Container\OrderIdentity::class, + OrderIdentity::class, ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId', 'getCopyMethod'] ); $this->identityContainerMock->expects($this->any()) ->method('getStore') ->will($this->returnValue($this->storeMock)); + $this->orderMock->method('getId') + ->willReturn(self::ORDER_ID); + $this->sender = new OrderSender( $this->templateContainerMock, $this->identityContainerMock, @@ -86,7 +97,7 @@ public function testSend($configValue, $forceSyncMode, $emailSendingResult, $sen ->method('getCopyMethod') ->willReturn('copy'); - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->any()) ->method('format') @@ -127,6 +138,7 @@ public function testSend($configValue, $forceSyncMode, $emailSendingResult, $sen ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'billing' => $addressMock, 'payment_html' => 'payment', 'store' => $this->storeMock, @@ -237,7 +249,7 @@ public function sendDataProvider() public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expectedShippingAddress) { $address = 'address_test'; - $this->orderMock->setData(\Magento\Sales\Api\Data\OrderInterface::IS_VIRTUAL, $isVirtualOrder); + $this->orderMock->setData(OrderInterface::IS_VIRTUAL, $isVirtualOrder); $createdAtFormatted='Oct 14, 2019, 4:11:58 PM'; $customerName = 'test customer'; $frontendStatusLabel = 'Complete'; @@ -260,7 +272,7 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->method('getCopyMethod') ->willReturn('copy'); - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->exactly($formatCallCount)) ->method('format') @@ -295,6 +307,7 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'billing' => $addressMock, 'payment_html' => 'payment', 'store' => $this->storeMock, diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php index dcd80646b168c..7dfda5f9e0b41 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Email/Sender/ShipmentSenderTest.php @@ -5,7 +5,14 @@ */ namespace Magento\Sales\Test\Unit\Model\Order\Email\Sender; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\Order\Email\Container\ShipmentIdentity; use Magento\Sales\Model\Order\Email\Sender\ShipmentSender; +use Magento\Sales\Model\Order\Shipment; +use Magento\Sales\Model\ResourceModel\Order\Shipment as ShipmentResource; +use Magento\Sales\Model\ResourceModel\EntityAbstract; +use PHPUnit\Framework\MockObject\MockObject; /** * Test for Magento\Sales\Model\Order\Email\Sender\ShipmentSender class @@ -15,18 +22,22 @@ */ class ShipmentSenderTest extends AbstractSenderTest { + private const SHIPMENT_ID = 1; + + private const ORDER_ID = 1; + /** - * @var \Magento\Sales\Model\Order\Email\Sender\ShipmentSender + * @var ShipmentSender */ protected $sender; /** - * @var \Magento\Sales\Model\Order\Shipment|\PHPUnit_Framework_MockObject_MockObject + * @var Shipment|MockObject */ protected $shipmentMock; /** - * @var \Magento\Sales\Model\ResourceModel\EntityAbstract|\PHPUnit_Framework_MockObject_MockObject + * @var EntityAbstract|MockObject */ protected $shipmentResourceMock; @@ -35,14 +46,15 @@ protected function setUp() $this->stepMockSetup(); $this->shipmentResourceMock = $this->createPartialMock( - \Magento\Sales\Model\ResourceModel\Order\Shipment::class, + ShipmentResource::class, ['saveAttribute'] ); $this->shipmentMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Shipment::class, + Shipment::class, [ 'getStore', + 'getId', '__wakeup', 'getOrder', 'setSendEmail', @@ -58,8 +70,13 @@ protected function setUp() ->method('getOrder') ->will($this->returnValue($this->orderMock)); + $this->shipmentMock->method('getId') + ->willReturn(self::SHIPMENT_ID); + $this->orderMock->method('getId') + ->willReturn(self::ORDER_ID); + $this->identityContainerMock = $this->createPartialMock( - \Magento\Sales\Model\Order\Email\Container\ShipmentIdentity::class, + ShipmentIdentity::class, ['getStore', 'isEnabled', 'getConfigValue', 'getTemplateId', 'getGuestTemplateId', 'getCopyMethod'] ); $this->identityContainerMock->expects($this->any()) @@ -107,7 +124,7 @@ public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $ema ->willReturn($configValue); if (!$configValue || $forceSyncMode) { - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->any()) ->method('format') @@ -151,7 +168,9 @@ public function testSend($configValue, $forceSyncMode, $customerNoteNotify, $ema ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'shipment' => $this->shipmentMock, + 'shipment_id' => self::SHIPMENT_ID, 'comment' => $customerNoteNotify ? $comment : '', 'billing' => $addressMock, 'payment_html' => 'payment', @@ -243,7 +262,7 @@ public function sendDataProvider() public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expectedShippingAddress) { $address = 'address_test'; - $this->orderMock->setData(\Magento\Sales\Api\Data\OrderInterface::IS_VIRTUAL, $isVirtualOrder); + $this->orderMock->setData(OrderInterface::IS_VIRTUAL, $isVirtualOrder); $customerName = 'Test Customer'; $frontendStatusLabel = 'Complete'; $isNotVirtual = false; @@ -257,7 +276,7 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with('sales_email/general/async_sending') ->willReturn(false); - $addressMock = $this->createMock(\Magento\Sales\Model\Order\Address::class); + $addressMock = $this->createMock(Address::class); $this->addressRenderer->expects($this->exactly($formatCallCount)) ->method('format') @@ -291,7 +310,9 @@ public function testSendVirtualOrder($isVirtualOrder, $formatCallCount, $expecte ->with( [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'shipment' => $this->shipmentMock, + 'shipment_id' => self::SHIPMENT_ID, 'comment' => '', 'billing' => $addressMock, 'payment_html' => 'payment', diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php index 2262fbf03c1a1..4bca8e6a4b730 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php @@ -5,96 +5,120 @@ */ namespace Magento\Sales\Test\Unit\Model\Order\Shipment\Sender; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Event\ManagerInterface; +use Magento\Payment\Helper\Data; +use Magento\Payment\Model\Info; +use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\Order\Address\Renderer; +use Magento\Sales\Model\Order\Email\Container\ShipmentIdentity; +use Magento\Sales\Model\Order\Email\Container\Template; +use Magento\Sales\Model\Order\Email\Sender; +use Magento\Sales\Model\Order\Email\SenderBuilderFactory; +use Magento\Sales\Model\Order\Shipment\Sender\EmailSender; +use Magento\Sales\Model\ResourceModel\Order\Shipment; +use Magento\Store\Model\Store; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; + /** * Unit test for email notification sender for Shipment. * * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class EmailSenderTest extends \PHPUnit\Framework\TestCase +class EmailSenderTest extends TestCase { + private const SHIPMENT_ID = 1; + + private const ORDER_ID = 1; + /** - * @var \Magento\Sales\Model\Order\Shipment\Sender\EmailSender + * @var EmailSender */ private $subject; /** - * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject + * @var Order|MockObject */ private $orderMock; /** - * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject + * @var Store|MockObject */ private $storeMock; /** - * @var \Magento\Sales\Model\Order\Email\Sender|\PHPUnit_Framework_MockObject_MockObject + * @var Sender|MockObject */ private $senderMock; /** - * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|MockObject */ private $loggerMock; /** - * @var \Magento\Sales\Api\Data\ShipmentInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ShipmentInterface|MockObject */ private $shipmentMock; /** - * @var \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ShipmentCommentCreationInterface|MockObject */ private $commentMock; /** - * @var \Magento\Sales\Model\Order\Address|\PHPUnit_Framework_MockObject_MockObject + * @var Address|MockObject */ private $addressMock; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ private $globalConfigMock; /** - * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ManagerInterface|MockObject */ private $eventManagerMock; /** - * @var \Magento\Payment\Model\Info|\PHPUnit_Framework_MockObject_MockObject + * @var Info|MockObject */ private $paymentInfoMock; /** - * @var \Magento\Payment\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + * @var Data|MockObject */ private $paymentHelperMock; /** - * @var \Magento\Sales\Model\ResourceModel\Order\Shipment|\PHPUnit_Framework_MockObject_MockObject + * @var Shipment|MockObject */ private $shipmentResourceMock; /** - * @var \Magento\Sales\Model\Order\Address\Renderer|\PHPUnit_Framework_MockObject_MockObject + * @var Renderer|MockObject */ private $addressRendererMock; /** - * @var \Magento\Sales\Model\Order\Email\Container\Template|\PHPUnit_Framework_MockObject_MockObject + * @var Template|MockObject */ private $templateContainerMock; /** - * @var \Magento\Sales\Model\Order\Email\Container\ShipmentIdentity|\PHPUnit_Framework_MockObject_MockObject + * @var ShipmentIdentity|MockObject */ private $identityContainerMock; /** - * @var \Magento\Sales\Model\Order\Email\SenderBuilderFactory|\PHPUnit_Framework_MockObject_MockObject + * @var SenderBuilderFactory|MockObject */ private $senderBuilderFactoryMock; @@ -103,11 +127,11 @@ class EmailSenderTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class) + $this->orderMock = $this->getMockBuilder(Order::class) ->disableOriginalConstructor() ->getMock(); - $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) + $this->storeMock = $this->getMockBuilder(Store::class) ->setMethods(['getStoreId']) ->disableOriginalConstructor() ->getMock(); @@ -119,21 +143,21 @@ protected function setUp() ->method('getStore') ->willReturn($this->storeMock); - $this->senderMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Email\Sender::class) + $this->senderMock = $this->getMockBuilder(Sender::class) ->disableOriginalConstructor() ->setMethods(['send', 'sendCopyTo']) ->getMock(); - $this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) + $this->loggerMock = $this->getMockBuilder(LoggerInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->shipmentMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Shipment::class) + $this->shipmentMock = $this->getMockBuilder(Order\Shipment::class) ->disableOriginalConstructor() - ->setMethods(['setSendEmail', 'setEmailSent']) + ->setMethods(['setSendEmail', 'setEmailSent', 'getId']) ->getMock(); - $this->commentMock = $this->getMockBuilder(\Magento\Sales\Api\Data\ShipmentCommentCreationInterface::class) + $this->commentMock = $this->getMockBuilder(ShipmentCommentCreationInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -141,7 +165,7 @@ protected function setUp() ->method('getComment') ->willReturn('Comment text'); - $this->addressMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Address::class) + $this->addressMock = $this->getMockBuilder(Address::class) ->disableOriginalConstructor() ->getMock(); @@ -151,16 +175,19 @@ protected function setUp() $this->orderMock->expects($this->any()) ->method('getShippingAddress') ->willReturn($this->addressMock); + $this->orderMock->expects($this->any()) + ->method('getId') + ->willReturn(self::ORDER_ID); - $this->globalConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + $this->globalConfigMock = $this->getMockBuilder(ScopeConfigInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) + $this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->paymentInfoMock = $this->getMockBuilder(\Magento\Payment\Model\Info::class) + $this->paymentInfoMock = $this->getMockBuilder(Info::class) ->disableOriginalConstructor() ->getMock(); @@ -168,7 +195,7 @@ protected function setUp() ->method('getPayment') ->willReturn($this->paymentInfoMock); - $this->paymentHelperMock = $this->getMockBuilder(\Magento\Payment\Helper\Data::class) + $this->paymentHelperMock = $this->getMockBuilder(Data::class) ->disableOriginalConstructor() ->getMock(); @@ -177,11 +204,11 @@ protected function setUp() ->with($this->paymentInfoMock, 1) ->willReturn('Payment Info Block'); - $this->shipmentResourceMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Shipment::class) + $this->shipmentResourceMock = $this->getMockBuilder(Shipment::class) ->disableOriginalConstructor() ->getMock(); - $this->addressRendererMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Address\Renderer::class) + $this->addressRendererMock = $this->getMockBuilder(Renderer::class) ->disableOriginalConstructor() ->getMock(); @@ -190,12 +217,12 @@ protected function setUp() ->with($this->addressMock, 'html') ->willReturn('Formatted address'); - $this->templateContainerMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Email\Container\Template::class) + $this->templateContainerMock = $this->getMockBuilder(Template::class) ->disableOriginalConstructor() ->getMock(); $this->identityContainerMock = $this->getMockBuilder( - \Magento\Sales\Model\Order\Email\Container\ShipmentIdentity::class + ShipmentIdentity::class ) ->disableOriginalConstructor() ->getMock(); @@ -205,13 +232,13 @@ protected function setUp() ->willReturn($this->storeMock); $this->senderBuilderFactoryMock = $this->getMockBuilder( - \Magento\Sales\Model\Order\Email\SenderBuilderFactory::class + SenderBuilderFactory::class ) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $this->subject = new \Magento\Sales\Model\Order\Shipment\Sender\EmailSender( + $this->subject = new EmailSender( $this->templateContainerMock, $this->identityContainerMock, $this->senderBuilderFactoryMock, @@ -247,6 +274,9 @@ public function testSend($configValue, $forceSyncMode, $isComment, $emailSending $this->commentMock = null; } + $this->shipmentMock->expects($this->any()) + ->method('getId') + ->willReturn(self::SHIPMENT_ID); $this->shipmentMock->expects($this->once()) ->method('setSendEmail') ->with($emailSendingResult); @@ -254,7 +284,9 @@ public function testSend($configValue, $forceSyncMode, $isComment, $emailSending if (!$configValue || $forceSyncMode) { $transport = [ 'order' => $this->orderMock, + 'order_id' => self::ORDER_ID, 'shipment' => $this->shipmentMock, + 'shipment_id' => self::SHIPMENT_ID, 'comment' => $isComment ? 'Comment text' : '', 'billing' => $this->addressMock, 'payment_html' => 'Payment Info Block', diff --git a/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/Status/OptionsTest.php b/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/Status/OptionsTest.php index fe285d29d703b..a62d62f96c560 100644 --- a/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/Status/OptionsTest.php +++ b/app/code/Magento/Sales/Test/Unit/Ui/Component/Listing/Column/Status/OptionsTest.php @@ -8,9 +8,10 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Sales\Model\ResourceModel\Order\Status\CollectionFactory; use Magento\Sales\Ui\Component\Listing\Column\Status\Options; +use PHPUnit\Framework\MockObject\MockObject; /** - * Class OptionsTest + * Class Options test for Listing Column Status */ class OptionsTest extends \PHPUnit\Framework\TestCase { @@ -20,7 +21,7 @@ class OptionsTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + * @var CollectionFactory|MockObject */ protected $collectionFactoryMock; @@ -54,7 +55,6 @@ public function testToOptionArray() [ 'value' => '1', 'label' => 'Label', - '__disableTmpl' => true ] ]; diff --git a/app/code/Magento/Sales/Ui/Component/Listing/Column/Status/Options.php b/app/code/Magento/Sales/Ui/Component/Listing/Column/Status/Options.php index 14964f16b701e..680064596d0a7 100644 --- a/app/code/Magento/Sales/Ui/Component/Listing/Column/Status/Options.php +++ b/app/code/Magento/Sales/Ui/Component/Listing/Column/Status/Options.php @@ -9,7 +9,7 @@ use Magento\Sales\Model\ResourceModel\Order\Status\CollectionFactory; /** - * Class Options + * Class Options for Listing Column Status */ class Options implements OptionSourceInterface { @@ -42,14 +42,6 @@ public function toOptionArray() { if ($this->options === null) { $options = $this->collectionFactory->create()->toOptionArray(); - - array_walk( - $options, - function (&$option) { - $option['__disableTmpl'] = true; - } - ); - $this->options = $options; } return $this->options; diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml index f46b8c11cc240..fc624bfd803b6 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/totals/adjustments.phtml @@ -5,33 +5,42 @@ */ ?> <?php $_source = $block->getSource() ?> -<?php if ($_source) : ?> +<?php if ($_source): ?> <tr> - <td class="label"><?= $block->escapeHtml($block->getShippingLabel()) ?><div id="shipping_amount_adv"></div></td> + <td class="label"> + <?= $block->escapeHtml($block->getShippingLabel()) ?> + <div id="shipping_amount_adv"></div> + </td> <td> <input type="text" name="creditmemo[shipping_amount]" - value="<?= $block->escapeHtmlAttr($block->getShippingAmount()) ?>" + value="<?= /* @noEscape */ $block->formatValue($block->getShippingAmount()) ?>" class="input-text admin__control-text not-negative-amount" id="shipping_amount" /> </td> </tr> <tr> - <td class="label"><?= $block->escapeHtml(__('Adjustment Refund')) ?><div id="adjustment_positive_adv"></div></td> + <td class="label"> + <?= $block->escapeHtml(__('Adjustment Refund')) ?> + <div id="adjustment_positive_adv"></div> + </td> <td> <input type="text" name="creditmemo[adjustment_positive]" - value="<?= $block->escapeHtmlAttr($_source->getBaseAdjustmentPositive()) ?>" + value="<?= /* @noEscape */ $block->formatValue($_source->getBaseAdjustmentPositive()) ?>" class="input-text admin__control-text not-negative-amount" id="adjustment_positive" /> </td> </tr> <tr> - <td class="label"><?= $block->escapeHtml(__('Adjustment Fee')) ?><div id="adjustment_negative_adv"></div></td> + <td class="label"> + <?= $block->escapeHtml(__('Adjustment Fee')) ?> + <div id="adjustment_negative_adv"></div> + </td> <td> <input type="text" name="creditmemo[adjustment_negative]" - value="<?= $block->escapeHtmlAttr($_source->getBaseAdjustmentNegative()) ?>" + value="<?= /* @noEscape */ $block->formatValue($_source->getBaseAdjustmentNegative()) ?>" class="input-text admin__control-text not-negative-amount" id="adjustment_negative"/> <script> @@ -39,12 +48,16 @@ //<![CDATA[ Validation.addAllThese([ - ['not-negative-amount', '<?= $block->escapeJs(__('Please enter a positive number in this field.')) ?>', function(v) { - if(v.length) - return /^\s*\d+([,.]\d+)*\s*%?\s*$/.test(v); - else - return true; - }] + [ + 'not-negative-amount', + '<?= $block->escapeJs(__('Please enter a positive number in this field.')) ?>', + function (v) { + if (v.length) + return /^\s*\d+([,.]\d+)*\s*%?\s*$/.test(v); + else + return true; + } + ] ]); if ($('shipping_amount')) { diff --git a/app/code/Magento/Sales/view/frontend/email/creditmemo_new.html b/app/code/Magento/Sales/view/frontend/email/creditmemo_new.html index 5ae6f5f9d82c7..f475503528dc9 100644 --- a/app/code/Magento/Sales/view/frontend/email/creditmemo_new.html +++ b/app/code/Magento/Sales/view/frontend/email/creditmemo_new.html @@ -22,6 +22,8 @@ "var store_hours":"Store Hours", "var creditmemo":"Credit Memo", "var order":"Order", +"var order_id": "Order DB Id", +"var creditmemo_id": "Credit Memo DB Id", "var order_data.is_not_virtual":"Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -82,7 +84,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_creditmemo_items" creditmemo=$creditmemo order=$order}} + {{layout handle="sales_email_order_creditmemo_items" creditmemo_id=$creditmemo_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/email/creditmemo_new_guest.html b/app/code/Magento/Sales/view/frontend/email/creditmemo_new_guest.html index 657de2aae2045..d8a8a0baeca98 100644 --- a/app/code/Magento/Sales/view/frontend/email/creditmemo_new_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/creditmemo_new_guest.html @@ -21,7 +21,9 @@ "var store_hours":"Store Hours", "var creditmemo":"Credit Memo", "var order":"Order", -"var order_data.is_not_virtual":"Order Type" +"var order_data.is_not_virtual":"Order Type", +"var order_id": "Order DB Id", +"var creditmemo_id": "Credit Memo DB Id" } @--> {{template config_path="design/email/header_template"}} @@ -80,7 +82,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_creditmemo_items" creditmemo=$creditmemo order=$order}} + {{layout handle="sales_email_order_creditmemo_items" creditmemo_id=$creditmemo_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/email/invoice_new.html b/app/code/Magento/Sales/view/frontend/email/invoice_new.html index 68773ee9d7570..c4818172449a2 100644 --- a/app/code/Magento/Sales/view/frontend/email/invoice_new.html +++ b/app/code/Magento/Sales/view/frontend/email/invoice_new.html @@ -22,6 +22,8 @@ "var store_hours":"Store Hours", "var invoice": "Invoice", "var order": "Order", +"var order_id": "Order DB Id", +"var invoice_id": "Invoice DB Id", "var order_data.is_not_virtual": "Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -82,7 +84,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout area="frontend" handle="sales_email_order_invoice_items" invoice=$invoice order=$order}} + {{layout area="frontend" handle="sales_email_order_invoice_items" invoice_id=$invoice_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/email/invoice_new_guest.html b/app/code/Magento/Sales/view/frontend/email/invoice_new_guest.html index 5053ccc2ac635..c06630fd249ab 100644 --- a/app/code/Magento/Sales/view/frontend/email/invoice_new_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/invoice_new_guest.html @@ -21,6 +21,8 @@ "var store_hours":"Store Hours", "var invoice": "Invoice", "var order": "Order", +"var order_id": "Order DB Id", +"var invoice_id": "Invoice DB Id", "var order_data.is_not_virtual": "Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -80,7 +82,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_invoice_items" invoice=$invoice order=$order}} + {{layout handle="sales_email_order_invoice_items" invoice_id=$invoice_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/email/order_new.html b/app/code/Magento/Sales/view/frontend/email/order_new.html index 13c436b131b82..a411e8d5b29b3 100644 --- a/app/code/Magento/Sales/view/frontend/email/order_new.html +++ b/app/code/Magento/Sales/view/frontend/email/order_new.html @@ -22,6 +22,7 @@ "var this.getUrl($store,'customer/account/',[_nosid:1])":"Customer Account URL", "var order_data.is_not_virtual":"Order Type", "var order":"Order", +"var order_id": "Order DB Id", "var order_data.customer_name":"Customer Name" } @--> @@ -90,7 +91,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_items" order=$order area="frontend"}} + {{layout handle="sales_email_order_items" order_id=$order_id area="frontend"}} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/email/order_new_guest.html b/app/code/Magento/Sales/view/frontend/email/order_new_guest.html index 866a1ad87f9b1..dc3a8e9f69aca 100644 --- a/app/code/Magento/Sales/view/frontend/email/order_new_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/order_new_guest.html @@ -21,6 +21,7 @@ "var store_email":"Store Email", "var store_hours":"Store Hours", "var order_data.is_not_virtual":"Order Type", +"var order_id": "Order DB Id", "var order":"Order" } @--> {{template config_path="design/email/header_template"}} @@ -85,7 +86,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_items" order=$order}} + {{layout handle="sales_email_order_items" order_id=$order_id }} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/email/shipment_new.html b/app/code/Magento/Sales/view/frontend/email/shipment_new.html index 39823a0c9d80b..39397979d2aaa 100644 --- a/app/code/Magento/Sales/view/frontend/email/shipment_new.html +++ b/app/code/Magento/Sales/view/frontend/email/shipment_new.html @@ -23,7 +23,9 @@ "var store_hours":"Store Hours", "var order_data.is_not_virtual": "Order Type", "var shipment": "Shipment", -"var order": "Order" +"var order": "Order", +"var order_id": "Order DB Id", +"var shipment_id": "Shipment DB Id" } @--> {{template config_path="design/email/header_template"}} @@ -59,7 +61,7 @@ <h1>{{trans "Your Shipment #%shipment_id for Order #%order_id" shipment_id=$ship </tr> </table> {{/depend}} - {{layout handle="sales_email_order_shipment_track" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_track" shipment_id=$shipment_id order_id=$order_id}} <table class="order-details"> <tr> <td class="address-details"> @@ -86,7 +88,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_items" shipment_id=$shipment_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html b/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html index ed2f52ed85066..54c7f08506497 100644 --- a/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/shipment_new_guest.html @@ -22,7 +22,9 @@ "var store_hours":"Store Hours", "var order_data.is_not_virtual": "Order Type", "var shipment": "Shipment", -"var order": "Order" +"var order": "Order", +"var order_id": "Order DB Id", +"var shipment_id": "Shipment DB Id" } @--> {{template config_path="design/email/header_template"}} @@ -57,7 +59,7 @@ <h1>{{trans "Your Shipment #%shipment_id for Order #%order_id" shipment_id=$ship </tr> </table> {{/depend}} - {{layout handle="sales_email_order_shipment_track" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_track" shipment_id=$shipment_id order_id=$order_id}} <table class="order-details"> <tr> <td class="address-details"> @@ -84,7 +86,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_items" shipment_id=$shipment_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_email_order_shipment_track.xml b/app/code/Magento/Sales/view/frontend/layout/sales_email_order_shipment_track.xml index bbc7f04ce94fd..489317cfa65c7 100644 --- a/app/code/Magento/Sales/view/frontend/layout/sales_email_order_shipment_track.xml +++ b/app/code/Magento/Sales/view/frontend/layout/sales_email_order_shipment_track.xml @@ -8,10 +8,10 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <update handle="sales_email_order_shipment_renderers"/> <body> - <block class="Magento\Framework\View\Element\Template" name="sales.order.email.shipment.track" template="Magento_Sales::email/shipment/track.phtml"> + <block class="Magento\Sales\Block\Order\Email\Shipment\Items" name="sales.order.email.shipment.track" template="Magento_Sales::email/shipment/track.phtml"> <arguments> <argument name="tracking_url" xsi:type="object">Magento\Sales\Block\DataProviders\Email\Shipment\TrackingUrl</argument> </arguments> </block> </body> -</page> \ No newline at end of file +</page> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml index 54a6f7a16bb23..34152ea06745c 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleAndVerifyRuleConditionAndFreeShippingIsAppliedTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="defaultSimpleProduct" stepKey="initialSimpleProduct"/> </before> <after> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml index 67e75d63e016e..221f80b887fe5 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml @@ -86,8 +86,7 @@ <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> <waitForPageLoad stepKey="waitForAddToCart"/> <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <actionGroup ref="StorefrontApplyCouponActionGroup" stepKey="applyCoupon"> <argument name="coupon" value="_defaultCoupon"/> </actionGroup> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml index 2bf96cf0377d4..e2a65685bd97e 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml @@ -78,8 +78,7 @@ <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> <waitForPageLoad stepKey="waitForAddToCart"/> <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <actionGroup ref="StorefrontApplyCouponActionGroup" stepKey="applyCoupon"> <argument name="coupon" value="_defaultCoupon"/> </actionGroup> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml index 9833231f8ed84..24c3a7cd44bc8 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml @@ -80,8 +80,7 @@ <click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addProductToCart"/> <waitForPageLoad stepKey="waitForAddToCart"/> <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <conditionalClick selector="{{StorefrontSalesRuleCartCouponSection.couponHeader}}" dependentSelector="{{StorefrontSalesRuleCartCouponSection.discountBlockActive}}" visible="false" stepKey="clickCouponHeader"/> <waitForElementVisible selector="{{StorefrontSalesRuleCartCouponSection.couponField}}" stepKey="waitForCouponField" /> <fillField selector="{{StorefrontSalesRuleCartCouponSection.couponField}}" userInput="{$grabCouponCode}" stepKey="fillCouponField"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml index 7365f3b7a3425..34714e9637d46 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForMatchingSubtotalAndVerifyRuleConditionIsAppliedTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="defaultSimpleProduct" stepKey="initialSimpleProduct"/> </before> <after> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml index 81c30d197759d..a3e6331e31cf6 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingCategoryAndVerifyRuleConditionIsAppliedTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="_defaultCategory" stepKey="createCategory"/> <actionGroup ref="FillAdminSimpleProductFormActionGroup" stepKey="fillProductFieldsInAdmin"> <argument name="category" value="$$createCategory$$"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml index 2685e004ba1e0..e9f7f3ec6c70a 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleWithMatchingTotalWeightAndVerifyRuleConditionIsAppliedTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="defaultSimpleProductWeight200" stepKey="initialSimpleProduct"/> </before> <after> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml index 4cc331eebc4ee..51e25d3a7e255 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml @@ -71,8 +71,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <!-- Should not see the discount yet because we have not set country --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="openEstimateShippingSection"/> <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml index 4d987c00884e1..420bc37d5c1b2 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml @@ -75,8 +75,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <!-- Should not see the discount yet because we have not filled in postcode --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="openEstimateShippingSection"/> <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml index ff0e011210785..279747f87d66d 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml @@ -73,8 +73,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <!-- Should not see the discount yet because we have only 1 item in our cart --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> @@ -87,8 +86,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage2"/> <!-- Now we should see the discount because we have more than 1 item --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage2"/> - <waitForPageLoad stepKey="waitForCartPage2"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage2"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$246.00" stepKey="seeSubtotal2"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$1.00" stepKey="seeDiscountTotal"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml index 036844562af50..a3f32c0781a52 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml @@ -71,8 +71,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <!-- Should not see the discount yet because we have not filled in postcode --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <click selector="{{CheckoutCartSummarySection.shippingHeading}}" stepKey="expandShipping"/> <checkOption selector="{{CheckoutCartSummarySection.flatRateShippingMethod}}" stepKey="selectFlatRateShipping"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml index efd82316f0b0a..39ac14315110e 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml @@ -71,8 +71,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/> <!-- Should not see the discount yet because we have not exceeded $200 --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage"/> - <waitForPageLoad stepKey="waitForCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$123.00" stepKey="seeSubtotal"/> <dontSeeElement selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="dontSeeDiscount"/> @@ -85,8 +84,7 @@ <waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage2"/> <!-- Now we should see the discount because we exceeded $200 --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCartPage2"/> - <waitForPageLoad stepKey="waitForCartPage2"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCartPage2"/> <see selector="{{CheckoutCartSummarySection.subtotal}}" userInput="$246.00" stepKey="seeSubtotal2"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-$0.01" stepKey="seeDiscountTotal"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml index 172f6b6ba24c6..9b5f8fbb2912d 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartTotalValueWithFullDiscountUsingCartRuleTest.xml @@ -113,8 +113,7 @@ </actionGroup> <see selector="{{StorefrontMinicartSection.quantity}}" userInput="6" stepKey="seeCartQuantity"/> <!-- Go to the shopping cart page --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnPageShoppingCart"/> - <waitForPageLoad stepKey="waitForCheckoutPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="amOnPageShoppingCart"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.orderTotal}}" stepKey="waitForOrderTotalVisible"/> <selectOption selector="{{CheckoutCartSummarySection.country}}" userInput="United States" stepKey="selectCountry"/> <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForOrderTotalUpdate"/> diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/action/select-payment-method-mixin.js b/app/code/Magento/SalesRule/view/frontend/web/js/action/select-payment-method-mixin.js index 50d54d4e59789..0b8eba270b030 100644 --- a/app/code/Magento/SalesRule/view/frontend/web/js/action/select-payment-method-mixin.js +++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/select-payment-method-mixin.js @@ -7,10 +7,10 @@ define([ 'mage/utils/wrapper', 'Magento_Checkout/js/model/quote', 'Magento_SalesRule/js/model/payment/discount-messages', - 'Magento_Checkout/js/action/set-payment-information', + 'Magento_Checkout/js/action/set-payment-information-extended', 'Magento_Checkout/js/action/get-totals', 'Magento_SalesRule/js/model/coupon' -], function ($, wrapper, quote, messageContainer, setPaymentInformationAction, getTotalsAction, coupon) { +], function ($, wrapper, quote, messageContainer, setPaymentInformationExtended, getTotalsAction, coupon) { 'use strict'; return function (selectPaymentMethodAction) { @@ -20,11 +20,12 @@ define([ originalSelectPaymentMethodAction(paymentMethod); $.when( - setPaymentInformationAction( + setPaymentInformationExtended( messageContainer, { method: paymentMethod.method - } + }, + true ) ).done( function () { diff --git a/app/code/Magento/Search/Test/Unit/Ui/Component/Listing/Column/SynonymActionsTest.php b/app/code/Magento/Search/Test/Unit/Ui/Component/Listing/Column/SynonymActionsTest.php index d5563ec1cb289..5cf11e9babc25 100644 --- a/app/code/Magento/Search/Test/Unit/Ui/Component/Listing/Column/SynonymActionsTest.php +++ b/app/code/Magento/Search/Test/Unit/Ui/Component/Listing/Column/SynonymActionsTest.php @@ -112,7 +112,6 @@ public function testPrepareDataSourceWithItems() self::STUB_SYNONYM_GROUP_ID ) ], - '__disableTmpl' => true ], 'edit' => [ 'href' => sprintf( @@ -120,7 +119,6 @@ public function testPrepareDataSourceWithItems() self::STUB_SYNONYM_GROUP_ID ), 'label' => (string)__('View/Edit'), - '__disableTmpl' => true ] ] ] diff --git a/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php b/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php index f42ce50d2804b..2fd569642375e 100644 --- a/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php +++ b/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php @@ -64,12 +64,10 @@ public function prepareDataSource(array $dataSource) 'title' => __('Delete'), 'message' => __('Are you sure you want to delete synonym group with id: %1?', $item['group_id']) ], - '__disableTmpl' => true ]; $item[$name]['edit'] = [ 'href' => $this->urlBuilder->getUrl(self::SYNONYM_URL_PATH_EDIT, ['group_id' => $item['group_id']]), 'label' => __('View/Edit'), - '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Security/Test/Mftf/ActionGroup/AdminSaveUserInvalidExpirationActionGroup.xml b/app/code/Magento/Security/Test/Mftf/ActionGroup/AdminSaveUserInvalidExpirationActionGroup.xml index 02280ed809124..7cca38e68d8d1 100644 --- a/app/code/Magento/Security/Test/Mftf/ActionGroup/AdminSaveUserInvalidExpirationActionGroup.xml +++ b/app/code/Magento/Security/Test/Mftf/ActionGroup/AdminSaveUserInvalidExpirationActionGroup.xml @@ -16,7 +16,7 @@ <scrollToTopOfPage stepKey="scrollToTopOfPage"/> <click selector="{{AdminNewUserFormSection.userInfoTab}}" stepKey="openUserTab"/> <waitForPageLoad stepKey="waitForUserRoleTabOpened"/> - <see selector="{{AdminMessagesSection.errorMessage}}" userInput='"Expiration date" must be later than the current date.' + <see selector="{{AdminMessagesSection.error}}" userInput='"Expiration date" must be later than the current date.' stepKey="seeErrorMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithInvalidExpiration.xml b/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithInvalidExpiration.xml index 130dacfbc2237..3fb798521fb45 100644 --- a/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithInvalidExpiration.xml +++ b/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithInvalidExpiration.xml @@ -36,9 +36,9 @@ <actionGroup ref="AdminSaveUserSuccessActionGroup" stepKey="saveNewUserWithValidExpirationSuccess"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <wait time="120" stepKey="waitForUserToExpire"/> - <actionGroup ref="LoginAdminWithCredentialsActionGroup" stepKey="loginAsNewAdmin"> - <argument name="adminUser" value="{$grabUsername}"/> - <argument name="adminPassword" value="{$grabPassword}"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsNewAdmin"> + <argument name="username" value="{$grabUsername}"/> + <argument name="password" value="{$grabPassword}"/> </actionGroup> <actionGroup ref="AssertMessageOnAdminLoginActionGroup" stepKey="checkLoginMessage" /> diff --git a/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithValidExpiration.xml b/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithValidExpiration.xml index 39e4a3b56ca13..5d12650351bc0 100644 --- a/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithValidExpiration.xml +++ b/app/code/Magento/Security/Test/Mftf/Test/AdminLoginAdminUserWithValidExpiration.xml @@ -36,9 +36,9 @@ <grabValueFrom selector="{{AdminNewUserFormSection.password}}" stepKey="grabPassword"/> <actionGroup ref="AdminSaveUserSuccessActionGroup" stepKey="saveNewUserWithValidExpirationSuccess"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - <actionGroup ref="LoginAdminWithCredentialsActionGroup" stepKey="loginAsNewAdmin"> - <argument name="adminUser" value="{$grabUsername}"/> - <argument name="adminPassword" value="{$grabPassword}"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsNewAdmin"> + <argument name="username" value="{$grabUsername}"/> + <argument name="password" value="{$grabPassword}"/> </actionGroup> <actionGroup ref="AssertAdminDashboardPageIsVisibleActionGroup" stepKey="seeDashboardPage"/> diff --git a/app/code/Magento/Security/Test/Mftf/Test/AdminNavigateWhileUserExpiredTest.xml b/app/code/Magento/Security/Test/Mftf/Test/AdminNavigateWhileUserExpiredTest.xml index 1c251ea2b9ec2..c1a951afd87ec 100644 --- a/app/code/Magento/Security/Test/Mftf/Test/AdminNavigateWhileUserExpiredTest.xml +++ b/app/code/Magento/Security/Test/Mftf/Test/AdminNavigateWhileUserExpiredTest.xml @@ -40,9 +40,9 @@ <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <!-- Login as that user --> - <actionGroup ref="LoginAdminWithCredentialsActionGroup" stepKey="loginAsNewAdmin"> - <argument name="adminUser" value="{$grabUsername}"/> - <argument name="adminPassword" value="{$grabPassword}"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsNewAdmin"> + <argument name="username" value="{$grabUsername}"/> + <argument name="password" value="{$grabPassword}"/> </actionGroup> <actionGroup ref="AssertAdminDashboardPageIsVisibleActionGroup" stepKey="seeDashboardPage"/> <wait time="120" stepKey="waitForUserToExpire"/> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/GoToShipmentIntoOrderActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/GoToShipmentIntoOrderActionGroup.xml deleted file mode 100644 index 71341593ff036..0000000000000 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/GoToShipmentIntoOrderActionGroup.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="goToShipmentIntoOrder"> - <annotations> - <description>Clicks on the 'Ship' button on the view Admin Order page. Validates that the URL and Page Title are present and correct.</description> - </annotations> - - <click selector="{{AdminOrderDetailsMainActionsSection.ship}}" stepKey="clickShipAction"/> - <seeInCurrentUrl url="{{AdminShipmentNewPage.url}}" stepKey="seeOrderShipmentUrl"/> - <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Shipment" stepKey="seePageNameNewInvoicePage"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/SeeProductInShipmentItemsActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/SeeProductInShipmentItemsActionGroup.xml deleted file mode 100644 index 10ef44b090a8b..0000000000000 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/SeeProductInShipmentItemsActionGroup.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="seeProductInShipmentItems"> - <annotations> - <description>Validates that the provided Product is present and correct on the view Admin Order Shipment page under the 'Items Shipped' section.</description> - </annotations> - <arguments> - <argument name="product"/> - </arguments> - - <see selector="{{AdminShipmentItemsSection.skuColumn}}" userInput="{{product.sku}}" stepKey="seeProductSkuInGrid"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/SubmitShipmentIntoOrderActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/SubmitShipmentIntoOrderActionGroup.xml deleted file mode 100644 index c067a39e30f6c..0000000000000 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/SubmitShipmentIntoOrderActionGroup.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="submitShipmentIntoOrder"> - <annotations> - <description>Clicks on the 'Submit Shipment' button on the view Admin Order Shipment page. Validates that the URL and Page Title are present and correct.</description> - </annotations> - - <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="clickSubmitShipment"/> - <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPageShipping"/> - <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="seeShipmentCreateSuccess"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyBasicShipmentInformationActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyBasicShipmentInformationActionGroup.xml deleted file mode 100644 index 8d0d0e273e767..0000000000000 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/VerifyBasicShipmentInformationActionGroup.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="verifyBasicShipmentInformation"> - <annotations> - <description>Validates that the provided Customer, Shipping Address, Billing Address and Customer Group are present and correct on the view Admin Order page.</description> - </annotations> - <arguments> - <argument name="customer" defaultValue=""/> - <argument name="shippingAddress" defaultValue=""/> - <argument name="billingAddress" defaultValue=""/> - <argument name="customerGroup" defaultValue="GeneralCustomerGroup"/> - </arguments> - - <see selector="{{AdminShipmentOrderInformationSection.customerName}}" userInput="{{customer.firstname}}" stepKey="seeCustomerName"/> - <see selector="{{AdminShipmentOrderInformationSection.customerEmail}}" userInput="{{customer.email}}" stepKey="seeCustomerEmail"/> - <see selector="{{AdminShipmentOrderInformationSection.customerGroup}}" userInput="{{customerGroup.code}}" stepKey="seeCustomerGroup"/> - <see selector="{{AdminShipmentAddressInformationSection.billingAddress}}" userInput="{{billingAddress.street[0]}}" stepKey="seeBillingAddressStreet"/> - <see selector="{{AdminShipmentAddressInformationSection.billingAddress}}" userInput="{{billingAddress.city}}" stepKey="seeBillingAddressCity"/> - <see selector="{{AdminShipmentAddressInformationSection.billingAddress}}" userInput="{{billingAddress.country_id}}" stepKey="seeBillingAddressCountry"/> - <see selector="{{AdminShipmentAddressInformationSection.billingAddress}}" userInput="{{billingAddress.postcode}}" stepKey="seeBillingAddressPostcode"/> - <see selector="{{AdminShipmentAddressInformationSection.shippingAddress}}" userInput="{{shippingAddress.street[0]}}" stepKey="seeShippingAddressStreet"/> - <see selector="{{AdminShipmentAddressInformationSection.shippingAddress}}" userInput="{{shippingAddress.city}}" stepKey="seeShippingAddressCity"/> - <see selector="{{AdminShipmentAddressInformationSection.shippingAddress}}" userInput="{{shippingAddress.country_id}}" stepKey="seeShippingAddressCountry"/> - <see selector="{{AdminShipmentAddressInformationSection.shippingAddress}}" userInput="{{shippingAddress.postcode}}" stepKey="seeShippingAddressPostcode"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingCreateSitemapEntityActionGroup.xml b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingCreateSitemapEntityActionGroup.xml new file mode 100644 index 0000000000000..9a332c87217d1 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingCreateSitemapEntityActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + <!--Fill Required Fields --> + <actionGroup name="AdminMarketingCreateSitemapEntityActionGroup"> + <arguments> + <argument name="filename" type="string"/> + <argument name="path" type="string"/> + </arguments> + <fillField stepKey="fillFilenameField" selector="{{NewSiteMapSection.filename}}" userInput="{{filename}}"/> + <fillField stepKey="fillPathField" selector="{{NewSiteMapSection.path}}" userInput="{{path}}"/> + <!--Click the "Save" Button --> + <click stepKey="clickSaveButton" selector="{{NewSiteMapSection.saveButton}}"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingNavigateToNewSitemapPageActionGroup.xml b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingNavigateToNewSitemapPageActionGroup.xml new file mode 100644 index 0000000000000..c72e43c74ae5c --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingNavigateToNewSitemapPageActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + + <!--Click "Add New Sitemap Button" --> + <actionGroup name="AdminMarketingNavigateToNewSitemapPageActionGroup"> + <click stepKey="clickAddNewSitemapButton" selector="{{AdminMarketingSiteMapGridSection.add}}"/> + <waitForPageLoad stepKey="waitForNewNewsletterTemplatesPageLoaded"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingSearchSitemapActionGroup.xml b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingSearchSitemapActionGroup.xml new file mode 100644 index 0000000000000..76e0ddc58ea0d --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingSearchSitemapActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminMarketingSearchSitemapActionGroup"> + <arguments> + <argument name="name" type="string"/> + </arguments> + <!--Reset Search Filters --> + <conditionalClick selector="{{AdminDataGridHeaderSection.clearFilters}}" dependentSelector="{{AdminDataGridHeaderSection.clearFilters}}" visible="true" stepKey="clickClearFilters"/> + <!--Fill Sitemap Name Field --> + <fillField selector="{{AdminMarketingSiteMapGridSection.fileNameTextField}}" userInput="{{name}}" stepKey="filterByName"/> + <!--Click "Search" Button --> + <click selector="{{AdminMarketingSiteMapGridSection.searchButton}}" stepKey="doFilter"/> + <waitForPageLoad stepKey="waitForSitemapPageLoadedAfterFiltering"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingSitemapSearchActionGroup.xml b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingSitemapSearchActionGroup.xml new file mode 100644 index 0000000000000..6784cf51848b3 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AdminMarketingSitemapSearchActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminMarketingSitemapSearchActionGroup"> + <arguments> + <argument name="filename" type="string"/> + </arguments> + <click selector="{{AdminMarketingSiteMapGridSection.resetButton}}" stepKey="resetSearchFilter"/> + <fillField selector="{{AdminMarketingSiteMapGridSection.fileNameTextField}}" userInput="{{filename}}" stepKey="fillFileNameField"/> + <click selector="{{AdminMarketingSiteMapGridSection.searchButton}}" stepKey="clickSearchButton"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AssertAdminSitemapInGridActionGroup.xml b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AssertAdminSitemapInGridActionGroup.xml new file mode 100644 index 0000000000000..c844cb9a3ca76 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AssertAdminSitemapInGridActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertAdminSitemapInGridActionGroup"> + <arguments> + <argument name="name" type="string"/> + </arguments> + <see userInput="{{name}}" selector="{{AdminMarketingSiteMapGridSection.rowByIndex('1')}}" stepKey="seeSitemap"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AssertAdminSitemapIsNotInGridActionGroup.xml b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AssertAdminSitemapIsNotInGridActionGroup.xml new file mode 100644 index 0000000000000..c8effb45eda7a --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/ActionGroup/AssertAdminSitemapIsNotInGridActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AssertAdminSitemapIsNotInGridActionGroup"> + <arguments> + <argument name="filename" type="string"/> + </arguments> + <dontSee userInput="{{filename}}" selector="{{AdminMarketingSiteMapGridSection.firstSearchResult}}" stepKey="verifyThatCorrectStoreGroupFound"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sitemap/Test/Mftf/Data/SitemapData.xml b/app/code/Magento/Sitemap/Test/Mftf/Data/SitemapData.xml index 0b5d5d3dcdefe..b952f829b1d96 100644 --- a/app/code/Magento/Sitemap/Test/Mftf/Data/SitemapData.xml +++ b/app/code/Magento/Sitemap/Test/Mftf/Data/SitemapData.xml @@ -12,4 +12,8 @@ <data key="filename">sitemap.xml</data> <data key="path">/</data> </entity> + <entity name="UniqueSitemapName"> + <data key="filename" unique="prefix">sitemap.xml</data> + <data key="path">/</data> + </entity> </entities> diff --git a/app/code/Magento/Sitemap/Test/Mftf/Section/AdminMarketingSiteMapGridSection.xml b/app/code/Magento/Sitemap/Test/Mftf/Section/AdminMarketingSiteMapGridSection.xml index 50c96ae6748ce..d315cc24e8f96 100644 --- a/app/code/Magento/Sitemap/Test/Mftf/Section/AdminMarketingSiteMapGridSection.xml +++ b/app/code/Magento/Sitemap/Test/Mftf/Section/AdminMarketingSiteMapGridSection.xml @@ -9,6 +9,8 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminMarketingSiteMapGridSection"> + <element name="add" type="button" selector=".page-actions-buttons .add"/> + <element name="rowByIndex" type="text" selector="tr[data-role='row']:nth-of-type({{var1}})" parameterized="true" timeout="30"/> <element name="resetButton" type="button" selector="button[title='Reset Filter']"/> <element name="searchButton" type="button" selector=".admin__filter-actions [title='Search']"/> <element name="firstSearchResult" type="text" selector="#sitemapGrid_table>tbody>tr:nth-child(1)"/> diff --git a/app/code/Magento/Sitemap/Test/Mftf/Section/AdminMarketingSiteMapNewSection.xml b/app/code/Magento/Sitemap/Test/Mftf/Section/AdminMarketingSiteMapNewSection.xml new file mode 100644 index 0000000000000..a7908417b7ac3 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/Section/AdminMarketingSiteMapNewSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="NewSiteMapSection"> + <element name="filename" type="input" selector="#sitemap_filename"/> + <element name="path" type="input" selector="#sitemap_path"/> + <element name="saveButton" type="button" selector=".page-actions .save"/> + </section> +</sections> diff --git a/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapEntityTest.xml b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapEntityTest.xml new file mode 100644 index 0000000000000..94f0e0a0487d6 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapEntityTest.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> + <!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + --> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMarketingCreateSitemapEntityTest"> + <annotations> + <features value="Sitemap"/> + <stories value="Admin Creates Sitemap Entity"/> + <title value="Sitemap Creation"/> + <description value="Sitemap Entity Creation"/> + <testCaseId value="MC-14312"/> + <group value="sitemap"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + </before> + <after> + <actionGroup ref="AdminMarketingSiteDeleteByNameActionGroup" stepKey="deleteCreatedSitemap"> + <argument name="filename" value="sitemap.xml"/> + </actionGroup> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + </after> + + <!--TEST BODY --> + <!--Navigate to Marketing->Sitemap Page --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToMarketingSiteMapPage"> + <argument name="menuUiId" value="{{AdminMenuMarketing.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSEOAndSearchSiteMap.dataUiId}}"/> + </actionGroup> + <!-- Navigate to New Sitemap Creation Page --> + <actionGroup ref="AdminMarketingNavigateToNewSitemapPageActionGroup" stepKey="navigateToAddNewSitemap"/> + <!-- Create Sitemap Entity --> + <actionGroup ref="AdminMarketingCreateSitemapEntityActionGroup" stepKey="createSitemap"> + <argument name="filename" value="sitemap.xml"/> + <argument name="path" value="/"/> + </actionGroup> + <!-- Assert Success Message --> + <actionGroup ref="AssertMessageInAdminPanelActionGroup" stepKey="seeSuccessMessage"> + <argument name="message" value="You saved the sitemap."/> + <argument name="messageType" value="success"/> + </actionGroup> + <!-- Find Created Sitemap On Grid --> + <actionGroup ref="AdminMarketingSearchSitemapActionGroup" stepKey="findCreatedSitemapInGrid"> + <argument name="name" value="sitemap.xml"/> + </actionGroup> + <actionGroup ref="AssertAdminSitemapInGridActionGroup" stepKey="assertSitemapInGrid"> + <argument name="name" value="sitemap.xml"/> + </actionGroup> + <!--END TEST BODY --> + </test> +</tests> diff --git a/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapFailFolderSaveTest.xml b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapFailFolderSaveTest.xml new file mode 100644 index 0000000000000..ae51db561e27c --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapFailFolderSaveTest.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMarketingCreateSitemapFailFolderSaveTest"> + <annotations> + <features value="Sitemap"/> + <stories value="Admin Creates Sitemap Entity Fail Folder Save"/> + <title value="Sitemap Creation Fail Folder Save"/> + <description value="Sitemap Entity Creation Fail Folder Save"/> + <testCaseId value="MC-14314"/> + <group value="sitemap"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + </before> + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + </after> + + <!--TEST BODY --> + <!--Navigate to Marketing->Sitemap Page --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToMarketingSiteMapPage"> + <argument name="menuUiId" value="{{AdminMenuMarketing.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSEOAndSearchSiteMap.dataUiId}}"/> + </actionGroup> + <!-- Navigate to New Sitemap Creation Page --> + <actionGroup ref="AdminMarketingNavigateToNewSitemapPageActionGroup" stepKey="navigateToAddNewSitemap"/> + <!-- Create Sitemap Entity With Incorrect Folder--> + <actionGroup ref="AdminMarketingCreateSitemapEntityActionGroup" stepKey="createSitemap"> + <argument name="filename" value="sitemap.xml"/> + <argument name="path" value="%isolation%"/> + </actionGroup> + <!-- See Error Message--> + <actionGroup ref="AssertMessageInAdminPanelActionGroup" stepKey="seeErrorMessage"> + <argument name="message" value="Please create the specified folder "%isolation%" before saving the sitemap."/> + <argument value="error" name="messageType"/> + </actionGroup> + <!--END TEST BODY --> + </test> +</tests> diff --git a/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapPathErrorTest.xml b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapPathErrorTest.xml new file mode 100644 index 0000000000000..2300e05adce1d --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingCreateSitemapPathErrorTest.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMarketingCreateSitemapPathErrorTest"> + <annotations> + <features value="Sitemap"/> + <stories value="Admin Creates Sitemap Entity Path Error"/> + <title value="Sitemap Creation With Path Error"/> + <description value="Sitemap Entity Creation With Path Error"/> + <testCaseId value="MC-14313"/> + <group value="sitemap"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> + </before> + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logoutFromAdmin"/> + </after> + + <!--TEST BODY --> + + <!--Navigate to Marketing->Sitemap Page --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToMarketingSiteMapPage"> + <argument name="menuUiId" value="{{AdminMenuMarketing.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSEOAndSearchSiteMap.dataUiId}}"/> + </actionGroup> + <!-- Navigate to New Sitemap Creation Page --> + <actionGroup ref="AdminMarketingNavigateToNewSitemapPageActionGroup" stepKey="navigateToAddNewSitemap"/> + <!-- Create Sitemap Entity With Incorrect Path--> + <actionGroup ref="AdminMarketingCreateSitemapEntityActionGroup" stepKey="createSitemap"> + <argument name="filename" value="%isolation%"/> + <argument name="path" value="/"/> + </actionGroup> + <!-- See Error Message--> + <actionGroup ref="AssertMessageInAdminPanelActionGroup" stepKey="seeErrorMessage"> + <argument name="message" value="Path "/%isolation%" is not available and cannot be used."/> + <argument value="error" name="messageType"/> + </actionGroup> + <!--END TEST BODY --> + </test> +</tests> diff --git a/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingDeleteSitemapEntityTest.xml b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingDeleteSitemapEntityTest.xml new file mode 100644 index 0000000000000..44698b7a6bb56 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Mftf/Test/AdminMarketingDeleteSitemapEntityTest.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMarketingDeleteSitemapEntityTest"> + <annotations> + <features value="Sitemap"/> + <stories value="Admin Deletes Sitemap Entity Test"/> + <title value="Sitemap Deleting Test"/> + <description value="Admin Should Delete Sitemap Entity"/> + <testCaseId value="MC-14315"/> + <group value="sitemap"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> + <!--Navigate to Marketing->Sitemap Page --> + <actionGroup ref="AdminNavigateMenuActionGroup" stepKey="navigateToMarketingSiteMapPage"> + <argument name="menuUiId" value="{{AdminMenuMarketing.dataUiId}}"/> + <argument name="submenuUiId" value="{{AdminMenuSEOAndSearchSiteMap.dataUiId}}"/> + </actionGroup> + <!-- Navigate To New Sitemap Page --> + <actionGroup ref="AdminMarketingSiteMapNavigateNewActionGroup" stepKey="navigateToNewSitemapPage"/> + <!-- Create Sitemap Entity --> + <actionGroup ref="AdminMarketingSiteMapFillFormActionGroup" stepKey="createSitemap"> + <argument name="sitemap" value="UniqueSitemapName"/> + </actionGroup> + </before> + <after> + <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> + </after> + + <actionGroup ref="AdminMarketingSiteDeleteByNameActionGroup" stepKey="deleteCreatedSitemap"> + <argument name="filename" value="{{UniqueSitemapName.filename}}"/> + </actionGroup> + <actionGroup ref="AssertSiteMapDeleteSuccessActionGroup" stepKey="assertSuccessMessage"/> + <actionGroup ref="AdminMarketingSitemapSearchActionGroup" stepKey="searchDeletedSitemap"> + <argument name="filename" value="{{UniqueSitemapName.filename}}"/> + </actionGroup> + <actionGroup ref="AssertAdminSitemapIsNotInGridActionGroup" stepKey="dontSeeEntity"> + <argument name="filename" value="{{UniqueSitemapName.filename}}"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php index 09f5418bbd762..7d2bdcc93b686 100644 --- a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php @@ -11,7 +11,7 @@ use Magento\Store\Model\App\Emulation; /** - * Class ObserverTest + * Class for ObserverTest * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -28,54 +28,55 @@ class ObserverTest extends \PHPUnit\Framework\TestCase private $observer; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit\Framework\MockObject\MockObject */ private $scopeConfigMock; /** - * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory|\PHPUnit\Framework\MockObject\MockObject */ private $collectionFactoryMock; /** - * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection|\PHPUnit\Framework\MockObject\MockObject */ private $sitemapCollectionMock; /** - * @var \Magento\Sitemap\Model\Sitemap|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sitemap\Model\Sitemap|\PHPUnit\Framework\MockObject\MockObject */ private $sitemapMock; /** - * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit\Framework\MockObject\MockObject */ private $objectManagerMock; /** - * @var Emulation|\PHPUnit_Framework_MockObject_MockObject + * @var Emulation|\PHPUnit\Framework\MockObject\MockObject */ private $appEmulationMock; /** - * @var EmailNotification|\PHPUnit_Framework_MockObject_MockObject + * @var EmailNotification|\PHPUnit\Framework\MockObject\MockObject */ private $emailNotificationMock; protected function setUp() { - $this->objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) - ->getMock(); - $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) - ->getMock(); + $this->objectManagerMock = $this->createMock( + \Magento\Framework\ObjectManagerInterface::class + ); + $this->scopeConfigMock = $this->createMock( + \Magento\Framework\App\Config\ScopeConfigInterface::class + ); $this->collectionFactoryMock = $this->getMockBuilder( \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory::class )->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); - $this->sitemapCollectionMock = $this->createPartialMock( - \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection::class, - ['getIterator'] + $this->sitemapCollectionMock = $this->createMock( + \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection::class ); $this->sitemapMock = $this->createPartialMock( \Magento\Sitemap\Model\Sitemap::class, @@ -130,6 +131,10 @@ public function testScheduledGenerateSitemapsSendsExceptionEmail() ) ->willReturn('error-recipient@example.com'); + $this->emailNotificationMock->expects($this->once()) + ->method('sendErrors') + ->with([$exception]); + $this->observer->scheduledGenerateSitemaps(); } } diff --git a/app/code/Magento/Store/App/Config/Source/RuntimeConfigSource.php b/app/code/Magento/Store/App/Config/Source/RuntimeConfigSource.php index f732871114061..b8b0ede43c70d 100644 --- a/app/code/Magento/Store/App/Config/Source/RuntimeConfigSource.php +++ b/app/code/Magento/Store/App/Config/Source/RuntimeConfigSource.php @@ -9,6 +9,7 @@ use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Adapter\TableNotFoundException; /** * Config source. Retrieve all configuration for scopes from db @@ -53,15 +54,21 @@ public function __construct( */ public function get($path = '') { - if ($this->canUseDatabase()) { - return [ - 'websites' => $this->getEntities('store_website', 'code'), - 'groups' => $this->getEntities('store_group', 'group_id'), - 'stores' => $this->getEntities('store', 'code'), - ]; + $data = []; + try { + if ($this->canUseDatabase()) { + $data = [ + 'websites' => $this->getEntities('store_website', 'code'), + 'groups' => $this->getEntities('store_group', 'group_id'), + 'stores' => $this->getEntities('store', 'code'), + ]; + } + } catch (TableNotFoundException $exception) { + // database is empty or not setup + $data = []; } - return []; + return $data; } /** @@ -89,14 +96,13 @@ private function getEntities($table, $keyField) $data = []; $tableName = $this->resourceConnection->getTableName($table); // Check if db table exists before fetch data - if ($this->resourceConnection->getConnection()->isTableExists($tableName)) { - $entities = $this->getConnection()->fetchAll( - $this->getConnection()->select()->from($tableName) - ); - foreach ($entities as $entity) { - $data[$entity[$keyField]] = $entity; - } + $entities = $this->getConnection()->fetchAll( + $this->getConnection()->select()->from($tableName) + ); + + foreach ($entities as $entity) { + $data[$entity[$keyField]] = $entity; } return $data; @@ -109,6 +115,6 @@ private function getEntities($table, $keyField) */ private function canUseDatabase() { - return $this->deploymentConfig->get('db'); + return $this->deploymentConfig->isDbAvailable(); } } diff --git a/app/code/Magento/Store/Model/Config/Processor/Fallback.php b/app/code/Magento/Store/Model/Config/Processor/Fallback.php index 57ac3459ccb48..4e8b3bca14c92 100644 --- a/app/code/Magento/Store/Model/Config/Processor/Fallback.php +++ b/app/code/Magento/Store/Model/Config/Processor/Fallback.php @@ -8,8 +8,7 @@ use Magento\Framework\App\Config\Spi\PostProcessorInterface; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\ResourceConnection; -use Magento\Store\Api\Data\StoreInterface; -use Magento\Store\Api\Data\WebsiteInterface; +use Magento\Framework\DB\Adapter\TableNotFoundException; use Magento\Store\App\Config\Type\Scopes; use Magento\Store\Model\ResourceModel\Store; use Magento\Store\Model\ResourceModel\Store\AllStoresCollectionFactory; @@ -85,13 +84,7 @@ public function __construct( */ public function process(array $data) { - if ($this->deploymentConfig->isDbAvailable()) {//read only from db - $this->storeData = $this->storeResource->readAllStores(); - $this->websiteData = $this->websiteResource->readAllWebsites(); - } else { - $this->storeData = $this->scopes->get('stores'); - $this->websiteData = $this->scopes->get('websites'); - } + $this->loadScopes(); $defaultConfig = isset($data['default']) ? $data['default'] : []; $result = [ @@ -177,4 +170,28 @@ private function getWebsiteConfig(array $websites, $id) } return []; } + + /** + * Load config from database. + * + * @return void + */ + private function loadScopes(): void + { + $loaded = false; + try { + if ($this->deploymentConfig->isDbAvailable()) { + $this->storeData = $this->storeResource->readAllStores(); + $this->websiteData = $this->websiteResource->readAllWebsites(); + $loaded = true; + } + } catch (TableNotFoundException $exception) { + // database is empty or not setup + $loaded = false; + } + if (!$loaded) { + $this->storeData = $this->scopes->get('stores'); + $this->websiteData = $this->scopes->get('websites'); + } + } } diff --git a/app/code/Magento/Store/Model/ResourceModel/Store.php b/app/code/Magento/Store/Model/ResourceModel/Store.php index 7a2821987f9bf..cadbe1817aed2 100644 --- a/app/code/Magento/Store/Model/ResourceModel/Store.php +++ b/app/code/Magento/Store/Model/ResourceModel/Store.php @@ -166,16 +166,10 @@ protected function _changeGroup(\Magento\Framework\Model\AbstractModel $model) */ public function readAllStores() { - $stores = []; - if ($this->getConnection()->isTableExists($this->getMainTable())) { - $select = $this->getConnection() - ->select() - ->from($this->getTable($this->getMainTable())); - - $stores = $this->getConnection()->fetchAll($select); - } - - return $stores; + $select = $this->getConnection() + ->select() + ->from($this->getTable($this->getMainTable())); + return $this->getConnection()->fetchAll($select); } /** diff --git a/app/code/Magento/Store/Model/ResourceModel/Website.php b/app/code/Magento/Store/Model/ResourceModel/Website.php index 431a9d62e7c39..a59c7746bec6e 100644 --- a/app/code/Magento/Store/Model/ResourceModel/Website.php +++ b/app/code/Magento/Store/Model/ResourceModel/Website.php @@ -48,14 +48,12 @@ public function readAllWebsites() { $websites = []; $tableName = $this->getMainTable(); - if ($this->getConnection()->isTableExists($tableName)) { - $select = $this->getConnection() - ->select() - ->from($tableName); + $select = $this->getConnection() + ->select() + ->from($tableName); - foreach ($this->getConnection()->fetchAll($select) as $websiteData) { - $websites[$websiteData['code']] = $websiteData; - } + foreach ($this->getConnection()->fetchAll($select) as $websiteData) { + $websites[$websiteData['code']] = $websiteData; } return $websites; diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusDisabledVerifyErrorSaveMessageTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusDisabledVerifyErrorSaveMessageTest.xml index d4b5bc9a9b50f..0a7b7852c38d0 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusDisabledVerifyErrorSaveMessageTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusDisabledVerifyErrorSaveMessageTest.xml @@ -17,7 +17,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create website--> <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createWebsite"> <argument name="newWebsiteName" value="{{customWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyAbsenceOfDeleteButtonTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyAbsenceOfDeleteButtonTest.xml index dc24a2f635b52..aa39340013142 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyAbsenceOfDeleteButtonTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyAbsenceOfDeleteButtonTest.xml @@ -17,7 +17,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!-- Create store --> <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createFirstStore"> <argument name="website" value="{{_defaultWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml index 188300acc7015..929b3aade4022 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateCustomStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml @@ -17,7 +17,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!-- Create store --> <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createStore"> <argument name="website" value="{{_defaultWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateNewLocalizedStoreViewStatusEnabledTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateNewLocalizedStoreViewStatusEnabledTest.xml index faa9d38a2d6fe..abb44165abd13 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateNewLocalizedStoreViewStatusEnabledTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateNewLocalizedStoreViewStatusEnabledTest.xml @@ -17,7 +17,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndDefaultCategoryTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndDefaultCategoryTest.xml index aaac3e5ea08b6..d9cd4c8f9f177 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndDefaultCategoryTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndDefaultCategoryTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create website--> <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createWebsite"> <argument name="newWebsiteName" value="{{customWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndRootCategoryTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndRootCategoryTest.xml index 8091f01e1f7ec..e541204a636e2 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndRootCategoryTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithCustomWebsiteAndRootCategoryTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create root category--> <createData entity="NewRootCategory" stepKey="rootCategory"/> <createData entity="SimpleRootSubCategory" stepKey="category"> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithDefaultWebsiteAndDefaultCategoryTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithDefaultWebsiteAndDefaultCategoryTest.xml index a161abe767010..809210f3bc436 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithDefaultWebsiteAndDefaultCategoryTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupWithDefaultWebsiteAndDefaultCategoryTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <actionGroup ref="DeleteCustomStoreActionGroup" stepKey="deleteStoreGroup"> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusDisabledVerifyBackendAndFrontendTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusDisabledVerifyBackendAndFrontendTest.xml index 0207faf692f14..f2bfc7f7cea76 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusDisabledVerifyBackendAndFrontendTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusDisabledVerifyBackendAndFrontendTest.xml @@ -17,7 +17,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml index 767b452544714..5f2472a0c52ee 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreViewStatusEnabledVerifyBackendAndFrontendTest.xml @@ -17,7 +17,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteDefaultStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteDefaultStoreViewTest.xml index c010935233a5b..ef4590eaff741 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteDefaultStoreViewTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteDefaultStoreViewTest.xml @@ -17,7 +17,7 @@ <group value="store"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreGroupTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreGroupTest.xml index a3afddd794723..349bcfe8f31e0 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreGroupTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreGroupTest.xml @@ -20,7 +20,7 @@ <before> <magentoCLI command="config:set system/backup/functionality_enabled 1" stepKey="setEnableBackupToYes"/> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create custom store group--> <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewCustomStoreGroup"> <argument name="website" value="{{_defaultWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreViewTest.xml index c4e3f51e6138f..305b4540668e4 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreViewTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreViewTest.xml @@ -19,7 +19,7 @@ </annotations> <before> <magentoCLI command="config:set system/backup/functionality_enabled 1" stepKey="setEnableBackupToYes"/> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create custom store view--> <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createNewStoreView"> <argument name="StoreGroup" value="_defaultStoreGroup"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminMoveStoreToOtherGroupSameWebsiteTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminMoveStoreToOtherGroupSameWebsiteTest.xml index a94c1f8f66c7c..812fe6f2d4144 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminMoveStoreToOtherGroupSameWebsiteTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminMoveStoreToOtherGroupSameWebsiteTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!-- Create first store --> <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createFirstStore"> <argument name="website" value="{{_defaultWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAcceptAlertAndVerifyStoreViewFormTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAcceptAlertAndVerifyStoreViewFormTest.xml index 8d4e095d6ed87..09a33d5eb86a6 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAcceptAlertAndVerifyStoreViewFormTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAcceptAlertAndVerifyStoreViewFormTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create root category--> <createData entity="NewRootCategory" stepKey="rootCategory"/> <createData entity="SimpleRootSubCategory" stepKey="category"> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAndVerifyStoreViewFormTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAndVerifyStoreViewFormTest.xml index f8df1059fb1ef..1c5d58c13538e 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAndVerifyStoreViewFormTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreGroupAndVerifyStoreViewFormTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create custom store group--> <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewCustomStoreGroup"> <argument name="website" value="{{_defaultWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreViewTest.xml index f2e9e12821595..c7c846c51af4d 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreViewTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateStoreViewTest.xml @@ -18,7 +18,7 @@ <group value="mtf_migrated"/> </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create custom store view--> <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createNewStoreView"> <argument name="StoreGroup" value="_defaultStoreGroup"/> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateWebsiteTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateWebsiteTest.xml index e9f72e46e3973..1c1c0ae30f6b1 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateWebsiteTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateWebsiteTest.xml @@ -19,7 +19,7 @@ </annotations> <before> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <!--Create website--> <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createWebsite"> <argument name="newWebsiteName" value="{{customWebsite.name}}"/> diff --git a/app/code/Magento/Store/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php b/app/code/Magento/Store/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php index a8f76d0a28fee..cf1c4c62787a7 100644 --- a/app/code/Magento/Store/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Config/Source/RuntimeConfigSourceTest.php @@ -8,17 +8,20 @@ use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Adapter\TableNotFoundException; use Magento\Framework\DB\Select; use Magento\Store\App\Config\Source\RuntimeConfigSource; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; /** * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class RuntimeConfigSourceTest extends \PHPUnit\Framework\TestCase +class RuntimeConfigSourceTest extends TestCase { /** - * @var DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject + * @var DeploymentConfig|MockObject */ private $deploymentConfig; @@ -28,12 +31,12 @@ class RuntimeConfigSourceTest extends \PHPUnit\Framework\TestCase private $configSource; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $connection; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $resourceConnection; @@ -54,8 +57,7 @@ public function setUp() public function testGet() { $this->deploymentConfig->expects($this->any()) - ->method('get') - ->with('db') + ->method('isDbAvailable') ->willReturn(true); $this->resourceConnection->expects($this->any())->method('getConnection')->willReturn($this->connection); @@ -63,7 +65,6 @@ public function testGet() $selectMock->expects($this->any())->method('from')->willReturnSelf(); $this->connection->expects($this->any())->method('select')->willReturn($selectMock); $this->connection->expects($this->any())->method('fetchAll')->willReturn([]); - $this->assertEquals( [ 'websites' => [], @@ -74,13 +75,32 @@ public function testGet() ); } - public function testGenWhenDbNotAvailable() + public function testGetWhenDbIsNotAvailable() { $this->deploymentConfig->expects($this->once()) - ->method('get') - ->with('db') + ->method('isDbAvailable') ->willReturn(false); - $this->resourceConnection->expects($this->never())->method('getConnection'); + $this->resourceConnection->expects($this->never()) + ->method('getConnection'); + + $this->assertEquals([], $this->configSource->get()); + } + + public function testGetWhenDbIsEmpty() + { + $this->deploymentConfig->expects($this->once()) + ->method('isDbAvailable') + ->willReturn(true); + $this->connection->method('fetchAll') + ->willThrowException($this->createMock(TableNotFoundException::class)); + $selectMock = $this->createMock(Select::class); + $selectMock->method('from') + ->willReturnSelf(); + $this->connection->method('select') + ->willReturn($selectMock); + $this->resourceConnection->expects($this->once()) + ->method('getConnection') + ->willReturn($this->connection); $this->assertEquals([], $this->configSource->get()); } diff --git a/app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreTest.php b/app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreTest.php index 926764b989686..731850ba58dcb 100644 --- a/app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreTest.php @@ -11,22 +11,24 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Store\Model\ResourceModel\Store; use Magento\Framework\DB\Adapter\AdapterInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class StoreTest extends \PHPUnit\Framework\TestCase +class StoreTest extends TestCase { /** @var Store */ protected $model; /** - * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + * @var ResourceConnection|MockObject */ protected $resourceMock; - /** @var Select | \PHPUnit_Framework_MockObject_MockObject */ + /** @var Select | MockObject */ protected $select; /** - * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject + * @var AdapterInterface|MockObject */ protected $connectionMock; @@ -131,11 +133,6 @@ public function testReadAllStores() ->method('getTableName') ->willReturn($mainTable); - $this->connectionMock->expects($this->once()) - ->method('isTableExists') - ->with($mainTable) - ->willReturn(true); - $this->connectionMock->expects($this->once()) ->method('select') ->willReturn($this->select); @@ -152,39 +149,4 @@ public function testReadAllStores() $this->assertEquals($data, $this->model->readAllStores()); } - - public function testReadAllStoresNoDbTable() - { - $mainTable = 'no_store_table'; - $data = []; - - $this->resourceMock->expects($this->once()) - ->method('getConnection') - ->willReturn($this->connectionMock); - - $this->resourceMock->expects($this->once()) - ->method('getTableName') - ->willReturn($mainTable); - - $this->connectionMock->expects($this->once()) - ->method('isTableExists') - ->with($mainTable) - ->willReturn(false); - - $this->connectionMock->expects($this->never()) - ->method('select') - ->willReturn($this->select); - - $this->select->expects($this->never()) - ->method('from') - ->with($mainTable) - ->willReturnSelf(); - - $this->connectionMock->expects($this->never()) - ->method('fetchAll') - ->with($this->select) - ->willReturn($data); - - $this->assertEquals($data, $this->model->readAllStores()); - } } diff --git a/app/code/Magento/Store/Test/Unit/Model/ResourceModel/WebsiteTest.php b/app/code/Magento/Store/Test/Unit/Model/ResourceModel/WebsiteTest.php index 5fd5aa09a46be..6e8049e9e37e5 100644 --- a/app/code/Magento/Store/Test/Unit/Model/ResourceModel/WebsiteTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/ResourceModel/WebsiteTest.php @@ -10,22 +10,24 @@ use Magento\Framework\DB\Select; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Store\Model\ResourceModel\Website; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; -class WebsiteTest extends \PHPUnit\Framework\TestCase +class WebsiteTest extends TestCase { /** @var Website */ protected $model; /** - * @var \Magento\Framework\App\ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\App\ResourceConnection|MockObject */ protected $resourceMock; - /** @var Select | \PHPUnit_Framework_MockObject_MockObject */ + /** @var Select | MockObject */ protected $select; /** - * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\DB\Adapter\AdapterInterface|MockObject */ protected $connectionMock; @@ -79,11 +81,6 @@ public function testReadAllWebsites() ->method('getConnection') ->willReturn($this->connectionMock); - $this->connectionMock->expects($this->once()) - ->method('isTableExists') - ->with($mainTable) - ->willReturn(true); - $this->connectionMock->expects($this->once()) ->method('select') ->willReturn($this->select); @@ -101,41 +98,6 @@ public function testReadAllWebsites() $this->assertEquals($data, $this->model->readAllWebsites()); } - public function testReadAllWebsitesNoDbTable() - { - $data = []; - $mainTable = 'no_store_website_table'; - - $this->resourceMock->expects($this->once()) - ->method('getTableName') - ->willReturn($mainTable); - - $this->resourceMock->expects($this->atLeastOnce()) - ->method('getConnection') - ->willReturn($this->connectionMock); - - $this->connectionMock->expects($this->once()) - ->method('isTableExists') - ->with($mainTable) - ->willReturn(false); - - $this->connectionMock->expects($this->never()) - ->method('select') - ->willReturn($this->select); - - $this->select->expects($this->never()) - ->method('from') - ->with($mainTable) - ->willReturnSelf(); - - $this->connectionMock->expects($this->never()) - ->method('fetchAll') - ->with($this->select) - ->willReturn($data); - - $this->assertEquals($data, $this->model->readAllWebsites()); - } - public function testGetDefaultStoresSelect($includeDefault = false) { $storeId = 1; diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCheckTextSwatchAttributeAddedViaApiTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCheckTextSwatchAttributeAddedViaApiTest.xml index 6ac5f2a55f3cf..0fcf0c0a35033 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCheckTextSwatchAttributeAddedViaApiTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCheckTextSwatchAttributeAddedViaApiTest.xml @@ -31,7 +31,7 @@ <deleteData createDataKey="createTextSwatchConfigProductAttribute" stepKey="deleteAttribute"/> <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> <!-- Reindex invalidated indices after product attribute has been created/deleted --> - <actionGroup ref="CliRunReindexUsingCronJobsActionGroup" stepKey="reindexInvalidatedIndices"/> + <magentoCron groups="index" stepKey="reindexInvalidatedIndices"/> </after> <!-- Open the new simple product page --> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontCustomerCanChangeProductOptionsUsingSwatchesTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontCustomerCanChangeProductOptionsUsingSwatchesTest.xml index 32e447f6463c0..ab532538cc3f3 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontCustomerCanChangeProductOptionsUsingSwatchesTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontCustomerCanChangeProductOptionsUsingSwatchesTest.xml @@ -44,7 +44,7 @@ </actionGroup> <!-- Go to shopping cart and update option of configurable product --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="openShoppingCartPage"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="openShoppingCartPage"/> <actionGroup ref="StorefrontUpdateCartConfigurableProductWithSwatchesActionGroup" stepKey="updateConfigurableProductInTheCart"> <argument name="product" value="_defaultProduct"/> <argument name="productOption" value="e74d3c"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml index 47ca8ce44bec3..03c09c70f3654 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml @@ -30,8 +30,8 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteAttribute"> - <argument name="ProductAttribute" value="visualSwatchAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteAttribute"> + <argument name="productAttributeLabel" value="{{visualSwatchAttribute.default_label}}"/> </actionGroup> <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="openProductIndexPage"/> <actionGroup ref="ClearFiltersAdminDataGridActionGroup" stepKey="clearGridFilter"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml index a1d346ffa2744..5ae53858374e7 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchAttributesDisplayInWidgetCMSTest.xml @@ -36,12 +36,11 @@ <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="visitAdminProductPage"/> <waitForPageLoad stepKey="waitForAdminProductGridLoad"/> <conditionalClick selector="{{AdminProductGridFilterSection.clearFilters}}" dependentSelector="{{AdminProductGridFilterSection.clearFilters}}" visible="true" stepKey="clickClearFiltersInitial"/> - <actionGroup ref="DeleteProductAttributeByLabelActionGroup" stepKey="deleteAttribute"> - <argument name="ProductAttribute" value="visualSwatchAttribute"/> + <actionGroup ref="AdminDeleteProductAttributeByLabelActionGroup" stepKey="deleteAttribute"> + <argument name="productAttributeLabel" value="{{visualSwatchAttribute.default_label}}"/> </actionGroup> <!--delete root category--> - <amOnPage url="{{AdminCategoryPage.url}}" stepKey="navigateToCategoryPage"/> - <waitForPageLoad time="30" stepKey="waitForPageCategoryLoad"/> + <actionGroup ref="AdminOpenCategoryPageActionGroup" stepKey="navigateToCategoryPage"/> <click selector="{{AdminCategorySidebarTreeSection.categoryInTree('$$createRootCategory.name$$')}}" stepKey="clickOnDefaultRootCategory"/> <waitForPageLoad stepKey="waitForPageDefaultCategoryEditLoad" /> <seeElement selector="{{AdminCategoryMainActionsSection.DeleteButton}}" stepKey="assertDeleteButtonIsPresent1"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml index e027a41cd9d2a..1b77e773ef283 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml @@ -76,8 +76,7 @@ <see selector="{{StorefrontProductPageSection.messagesBlock}}" userInput="You added {{BaseConfigurableProduct.name}} to your shopping cart." stepKey="seeSuccessMessage"/> <!--Check item in cart--> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCart"/> - <waitForPageLoad stepKey="waitForCartPageLoad"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCart"/> <seeElement selector="{{CheckoutCartProductSection.ProductLinkByName(BaseConfigurableProduct.name)}}" stepKey="seeProductInCart"/> <see selector="{{CheckoutCartProductSection.ProductOptionByNameAndAttribute(BaseConfigurableProduct.name, visualSwatchAttribute.default_label)}}" userInput="{{visualSwatchOption2.default_label}}" stepKey="seeSelectedSwatch"/> <see selector="{{CheckoutCartProductSection.ProductOptionByNameAndAttribute(BaseConfigurableProduct.name, ProductOptionFile.title)}}" userInput="{{MagentoLogo.file}}" stepKey="seeCorrectOptionFile"/> diff --git a/app/code/Magento/Tax/Model/Layout/DepersonalizePlugin.php b/app/code/Magento/Tax/Model/Layout/DepersonalizePlugin.php index ad17406c34b75..6959f0a0d7c7c 100644 --- a/app/code/Magento/Tax/Model/Layout/DepersonalizePlugin.php +++ b/app/code/Magento/Tax/Model/Layout/DepersonalizePlugin.php @@ -1,85 +1,86 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Tax\Model\Layout; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\View\LayoutInterface; use Magento\PageCache\Model\DepersonalizeChecker; /** - * Class DepersonalizePlugin + * Depersonalize customer data. + * + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class DepersonalizePlugin { /** * @var DepersonalizeChecker */ - protected $depersonalizeChecker; + private $depersonalizeChecker; /** - * @var \Magento\Customer\Model\Session + * @var CustomerSession */ - protected $customerSession; + private $customerSession; /** * @var array */ - protected $defaultTaxShippingAddress; + private $defaultTaxShippingAddress; /** * @var array */ - protected $defaultTaxBillingAddress; + private $defaultTaxBillingAddress; /** * @var int */ - protected $customerTaxClassId; + private $customerTaxClassId; /** * @param DepersonalizeChecker $depersonalizeChecker - * @param \Magento\Customer\Model\Session $customerSession + * @param CustomerSession $customerSession */ public function __construct( DepersonalizeChecker $depersonalizeChecker, - \Magento\Customer\Model\Session $customerSession + CustomerSession $customerSession ) { - $this->customerSession = $customerSession; $this->depersonalizeChecker = $depersonalizeChecker; + $this->customerSession = $customerSession; } /** - * Before generate Xml + * Resolve sensitive customer data if the depersonalization is needed. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @return array + * @param LayoutInterface $subject + * @return void */ - public function beforeGenerateXml(\Magento\Framework\View\LayoutInterface $subject) + public function beforeGenerateXml(LayoutInterface $subject) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->defaultTaxBillingAddress = $this->customerSession->getDefaultTaxBillingAddress(); $this->defaultTaxShippingAddress = $this->customerSession->getDefaultTaxShippingAddress(); $this->customerTaxClassId = $this->customerSession->getCustomerTaxClassId(); } - return []; } /** - * After generate Xml + * Change sensitive customer data if the depersonalization is needed. * - * @param \Magento\Framework\View\LayoutInterface $subject - * @param \Magento\Framework\View\LayoutInterface $result - * @return \Magento\Framework\View\LayoutInterface + * @param LayoutInterface $subject + * @return void */ - public function afterGenerateXml(\Magento\Framework\View\LayoutInterface $subject, $result) + public function afterGenerateElements(LayoutInterface $subject) { if ($this->depersonalizeChecker->checkIfDepersonalize($subject)) { $this->customerSession->setDefaultTaxBillingAddress($this->defaultTaxBillingAddress); $this->customerSession->setDefaultTaxShippingAddress($this->defaultTaxShippingAddress); $this->customerSession->setCustomerTaxClassId($this->customerTaxClassId); } - return $result; } } diff --git a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminCreateTaxRuleCustomProductTaxClassActionGroup.xml b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminCreateTaxRuleCustomProductTaxClassActionGroup.xml index 377985a81af37..a1a488c2e4e37 100644 --- a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminCreateTaxRuleCustomProductTaxClassActionGroup.xml +++ b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminCreateTaxRuleCustomProductTaxClassActionGroup.xml @@ -25,7 +25,7 @@ <click selector="{{AdminTaxRulesSection.selectProductTaxClass(taxableGoodsTaxClass.class_name)}}" stepKey="unSelectTaxClass"/> <click selector="{{AdminTaxRulesSection.selectProductTaxClass(productTaxClassName)}}" stepKey="selectProductTaxClass"/> <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSave"/> - <waitForElementVisible selector="{{AdminMessagesSection.successMessage}}" stepKey="waitForSuccessMessage"/> - <see selector="{{AdminMessagesSection.successMessage}}" userInput="You saved the tax rule." stepKey="verifyRuleSaved"/> + <waitForElementVisible selector="{{AdminMessagesSection.success}}" stepKey="waitForSuccessMessage"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You saved the tax rule." stepKey="verifyRuleSaved"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckingTaxReportGridTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckingTaxReportGridTest.xml index 0990daf1ecfbf..01e1677ec8d8a 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckingTaxReportGridTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminCheckingTaxReportGridTest.xml @@ -123,7 +123,7 @@ </after> <!--Open Created product. In Tax Class select new created Product Tax class.--> - <actionGroup ref="GoToProductPageViaIDActionGroup" stepKey="openProductForEdit"> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="openProductForEdit"> <argument name="productId" value="$createFirstProduct.id$"/> </actionGroup> <selectOption selector="{{AdminProductFormSection.productTaxClass}}" userInput="$productTaxClass.class_name$" stepKey="selectTexClassForProduct"/> @@ -131,7 +131,7 @@ <actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct"/> <!--Open Created Second Product. In Tax Class select new created Product Tax class.--> - <actionGroup ref="GoToProductPageViaIDActionGroup" stepKey="openSecondProductForEdit"> + <actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="openSecondProductForEdit"> <argument name="productId" value="$createSecondProduct.id$"/> </actionGroup> @@ -181,9 +181,9 @@ <actionGroup ref="SubmitInvoiceActionGroup" stepKey="clickSubmitInvoice"/> - <actionGroup ref="goToShipmentIntoOrder" stepKey="seeShipmentOrderPage"/> + <actionGroup ref="GoToShipmentIntoOrderActionGroup" stepKey="seeShipmentOrderPage"/> <!--Submit Shipment--> - <actionGroup ref="submitShipmentIntoOrder" stepKey="clickSubmitShipment"/> + <actionGroup ref="SubmitShipmentIntoOrderActionGroup" stepKey="clickSubmitShipment"/> <!--Go to "Reports" -> "Sales" -> "Tax"--> <amOnPage url="{{AdminSalesTaxReportPage.url}}" stepKey="navigateToReportsTaxPage"/> <waitForPageLoad stepKey="waitForReportsTaxPageLoad"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml index 959aa323308be..b1e91886960c5 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml @@ -82,8 +82,7 @@ <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> <!-- Assert that taxes are applied correctly for CA --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForCart"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckout"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml index c1268638c7104..8a04156f3d857 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml @@ -82,8 +82,7 @@ <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> <!-- Assert that taxes are applied correctly for NY --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForCart"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckout"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <!-- Assert that taxes are applied correctly for CA --> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml index 609c8c7b27980..b76f015679ae2 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml @@ -43,8 +43,14 @@ <magentoCLI command="cron:run --group=index" stepKey="runCronIndexer"/> <!-- Fill out form for a new user with address --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="Simple_US_Customer_NY"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <actionGroup ref="EnterCustomerAddressInfoActionGroup" stepKey="enterAddressInfo"> @@ -90,8 +96,7 @@ <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> <!-- Assert that taxes are applied correctly for NY --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForCart"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckout"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml index 724831d9409be..5f98093ec874f 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml @@ -42,8 +42,14 @@ <click stepKey="clickSave" selector="{{AdminStoresMainActionsSection.saveButton}}"/> <!-- Fill out form for a new user with address --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="Simple_US_Customer_NY"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> <actionGroup ref="EnterCustomerAddressInfoActionGroup" stepKey="enterAddressInfo"> @@ -89,8 +95,7 @@ <see stepKey="seeSuccess" selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You added"/> <!-- Assert that taxes are applied correctly for NY --> - <amOnPage url="{{CheckoutCartPage.url}}" stepKey="goToCheckout"/> - <waitForPageLoad stepKey="waitForCart"/> + <actionGroup ref="StorefrontCartPageOpenActionGroup" stepKey="goToCheckout"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <waitForElementVisible stepKey="waitForOverviewVisible" selector="{{CheckoutPaymentSection.tax}}"/> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml index 3a67276c42737..18a1a11d35fd2 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml @@ -75,11 +75,17 @@ </after> <!-- Fill out form for a new user with address --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="Simple_US_Customer_NY"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> - <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <actionGroup ref="EnterCustomerAddressInfoActionGroup" stepKey="enterAddressInfo"> <argument name="Address" value="US_Address_NY"/> </actionGroup> diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml index 793468b7f0b1e..35a483da7f690 100644 --- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml +++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml @@ -75,11 +75,17 @@ </after> <!-- Fill out form for a new user with address --> - <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> - <argument name="Customer" value="Simple_US_Customer_NY"/> + <actionGroup ref="StorefrontOpenCustomerAccountCreatePageActionGroup" stepKey="openCreateAccountPage"/> + <actionGroup ref="StorefrontFillCustomerAccountCreationFormActionGroup" stepKey="fillCreateAccountForm"> + <argument name="customer" value="Simple_US_Customer_NY"/> + </actionGroup> + <actionGroup ref="StorefrontClickCreateAnAccountCustomerAccountCreationFormActionGroup" stepKey="submitCreateAccountForm"/> + <actionGroup ref="AssertMessageCustomerCreateAccountActionGroup" stepKey="seeSuccessMessage"> + <argument name="messageType" value="success"/> + <argument name="message" value="Thank you for registering with Main Website Store."/> </actionGroup> - <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddressInfo"> + <actionGroup ref="EnterCustomerAddressInfoActionGroup" stepKey="enterAddressInfo"> <argument name="Address" value="US_Address_NY"/> </actionGroup> diff --git a/app/code/Magento/Tax/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Tax/Test/Unit/Model/Layout/DepersonalizePluginTest.php new file mode 100644 index 0000000000000..26ceef5f6ac3b --- /dev/null +++ b/app/code/Magento/Tax/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -0,0 +1,166 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Tax\Test\Unit\Model\Layout; + +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\LayoutInterface; +use Magento\PageCache\Model\DepersonalizeChecker; +use Magento\Tax\Model\Layout\DepersonalizePlugin; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * Unit tests for \Magento\Tax\Model\Layout\DepersonalizePlugin class. + */ +class DepersonalizePluginTest extends TestCase +{ + /** + * @var CustomerSession|MockObject + */ + private $customerSessionMock; + + /** + * @var DepersonalizePlugin + */ + private $plugin; + + /** + * @var DepersonalizeChecker|MockObject + */ + private $depersonalizeCheckerMock; + + /** + * @var LayoutInterface|MockObject + */ + private $layoutMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->customerSessionMock = $this->createPartialMock( + CustomerSession::class, + [ + 'getDefaultTaxBillingAddress', + 'getDefaultTaxShippingAddress', + 'getCustomerTaxClassId', + 'setDefaultTaxBillingAddress', + 'setDefaultTaxShippingAddress', + 'setCustomerTaxClassId', + ] + ); + $this->depersonalizeCheckerMock = $this->createMock(DepersonalizeChecker::class); + $this->layoutMock = $this->getMockForAbstractClass(LayoutInterface::class); + + $this->plugin = (new ObjectManagerHelper($this))->getObject( + DepersonalizePlugin::class, + [ + 'customerSession' => $this->customerSessionMock, + 'depersonalizeChecker' => $this->depersonalizeCheckerMock, + ] + ); + } + + /** + * Test beforeGenerateXml method when depersonalization is needed. + * + * @return void + */ + public function testBeforeGenerateXml(): void + { + $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); + $this->customerSessionMock->expects($this->once())->method('getDefaultTaxBillingAddress'); + $this->customerSessionMock->expects($this->once())->method('getDefaultTaxShippingAddress'); + $this->customerSessionMock->expects($this->once())->method('getCustomerTaxClassId'); + $this->plugin->beforeGenerateXml($this->layoutMock); + } + + /** + * Test beforeGenerateXml method when depersonalization is not needed. + * + * @return void + */ + public function testBeforeGenerateXmlNoDepersonalize(): void + { + $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); + $this->customerSessionMock->expects($this->never())->method('getDefaultTaxBillingAddress'); + $this->customerSessionMock->expects($this->never())->method('getDefaultTaxShippingAddress'); + $this->customerSessionMock->expects($this->never())->method('getCustomerTaxClassId'); + $this->plugin->beforeGenerateXml($this->layoutMock); + } + + /** + * Test afterGenerateElements method when depersonalization is needed. + * + * @return void + */ + public function testAfterGenerateElements(): void + { + $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(true); + $this->customerSessionMock->expects($this->once())->method('setDefaultTaxBillingAddress'); + $this->customerSessionMock->expects($this->once())->method('setDefaultTaxShippingAddress'); + $this->customerSessionMock->expects($this->once())->method('setCustomerTaxClassId'); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); + } + + /** + * Test afterGenerateElements method when depersonalization is not needed. + * + * @return void + */ + public function testAfterGenerateElementsNoDepersonalize(): void + { + $this->depersonalizeCheckerMock->expects($this->once())->method('checkIfDepersonalize')->willReturn(false); + $this->customerSessionMock->expects($this->never())->method('setDefaultTaxBillingAddress'); + $this->customerSessionMock->expects($this->never())->method('setDefaultTaxShippingAddress'); + $this->customerSessionMock->expects($this->never())->method('setCustomerTaxClassId'); + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); + } + + /** + * Test beforeGenerateXml and afterGenerateElements methods. + * + * @return void + */ + public function testBeforeAndAfter(): void + { + $defaultTaxBillingAddress = []; + $defaultTaxShippingAddress = []; + $customerTaxClassId = 1; + + $this->depersonalizeCheckerMock->expects($this->exactly(2)) + ->method('checkIfDepersonalize') + ->willReturn(true); + + $this->customerSessionMock->expects($this->once()) + ->method('getDefaultTaxBillingAddress') + ->willReturn($defaultTaxBillingAddress); + $this->customerSessionMock->expects($this->once()) + ->method('getDefaultTaxShippingAddress') + ->willReturn($defaultTaxShippingAddress); + $this->customerSessionMock->expects($this->once()) + ->method('getCustomerTaxClassId') + ->willReturn($customerTaxClassId); + + $this->plugin->beforeGenerateXml($this->layoutMock); + + $this->customerSessionMock->expects($this->once()) + ->method('setDefaultTaxBillingAddress') + ->with($defaultTaxBillingAddress); + $this->customerSessionMock->expects($this->once()) + ->method('setDefaultTaxShippingAddress') + ->with($defaultTaxShippingAddress); + $this->customerSessionMock->expects($this->once()) + ->method('setCustomerTaxClassId') + ->with($customerTaxClassId); + + $this->assertEmpty($this->plugin->afterGenerateElements($this->layoutMock)); + } +} diff --git a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php index 22cc1c9e89fbe..5cd27c58d6665 100644 --- a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php +++ b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/EditActionTest.php @@ -8,22 +8,23 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Store\Model\ScopeInterface; use Magento\Theme\Ui\Component\Listing\Column\EditAction; +use PHPUnit\Framework\MockObject\MockObject; /** - * Class EditActionTest + * Class EditAction test for Listing Column */ class EditActionTest extends \PHPUnit\Framework\TestCase { /** @var EditAction */ protected $component; - /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponent\ContextInterface|MockObject */ protected $context; - /** @var \Magento\Framework\View\Element\UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponentFactory|MockObject */ protected $uiComponentFactory; - /** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\UrlInterface|MockObject */ protected $urlBuilder; public function setup() @@ -67,7 +68,6 @@ public function testPrepareDataSource($dataSourceItem, $scope, $scopeId) 'edit' => [ 'href' => 'http://magento.com/theme/design_config/edit', 'label' => new \Magento\Framework\Phrase('Edit'), - '__disableTmpl' => true, ] ], ]; diff --git a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php index 5e2fe51043885..a7b5624236b2f 100644 --- a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php +++ b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php @@ -11,6 +11,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\UrlInterface; use Magento\Theme\Ui\Component\Listing\Column\ViewAction; +use PHPUnit\Framework\MockObject\MockObject; /** * Class ViewActionTest contains unit tests for \Magento\Theme\Ui\Component\Listing\Column\ViewAction class @@ -25,7 +26,7 @@ class ViewActionTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var UrlInterface|\PHPUnit_Framework_MockObject_MockObject + * @var UrlInterface|MockObject */ protected $urlBuilder; @@ -112,7 +113,6 @@ public function getPrepareDataSourceDataProvider() 'view' => [ 'href' => 'url', 'label' => __('View'), - '__disableTmpl' => true, ] ], 'entity_id' => 1 @@ -139,7 +139,6 @@ public function getPrepareDataSourceDataProvider() 'view' => [ 'href' => 'url', 'label' => __('View'), - '__disableTmpl' => true, ] ], 'theme_id' => 2 diff --git a/app/code/Magento/Theme/Ui/Component/Design/Config/SearchRobots/ResetButton.php b/app/code/Magento/Theme/Ui/Component/Design/Config/SearchRobots/ResetButton.php index 5a8829851e8cf..4b71fc6faba15 100644 --- a/app/code/Magento/Theme/Ui/Component/Design/Config/SearchRobots/ResetButton.php +++ b/app/code/Magento/Theme/Ui/Component/Design/Config/SearchRobots/ResetButton.php @@ -76,6 +76,7 @@ public function prepare() [ 'actionName' => 'reset', 'targetName' => '${ $.name }', + '__disableTmpl' => ['targetName' => false], 'params' => [ json_encode($this->getRobotsDefaultCustomInstructions()) ] diff --git a/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php b/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php index 1eeeaccff88ce..821eee8114bae 100644 --- a/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php +++ b/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php @@ -13,7 +13,7 @@ use Magento\Ui\Component\Listing\Columns\Column; /** - * Class EditAction + * Class EditAction for Listing Column */ class EditAction extends Column { @@ -74,7 +74,6 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Edit'), - '__disableTmpl' => true, ] ]; } diff --git a/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php b/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php index 9e47e2c52bddf..a49e622b9d42a 100644 --- a/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php +++ b/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php @@ -14,7 +14,7 @@ use Magento\Ui\Component\Listing\Columns\Column; /** - * Class ViewAction + * Class ViewAction for Listing Column */ class ViewAction extends Column { @@ -66,7 +66,6 @@ public function prepareDataSource(array $dataSource) : array ] ), 'label' => __('View'), - '__disableTmpl' => true, ] ]; } diff --git a/app/code/Magento/Translation/Model/FileManager.php b/app/code/Magento/Translation/Model/FileManager.php index 95fb3f2a5d4e9..4690fae763bfa 100644 --- a/app/code/Magento/Translation/Model/FileManager.php +++ b/app/code/Magento/Translation/Model/FileManager.php @@ -9,10 +9,11 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem\Driver\File; +use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\View\Asset\Repository; /** - * A service for handling Translation config files + * A service for handling Translation config files. */ class FileManager { @@ -36,23 +37,31 @@ class FileManager */ private $driverFile; + /** + * @var Json + */ + private $serializer; + /** * @param Repository $assetRepo * @param DirectoryList $directoryList * @param File $driverFile + * @param Json $serializer */ public function __construct( Repository $assetRepo, DirectoryList $directoryList, - File $driverFile + File $driverFile, + Json $serializer ) { $this->assetRepo = $assetRepo; $this->directoryList = $directoryList; $this->driverFile = $driverFile; + $this->serializer = $serializer; } /** - * Create a view asset representing the requirejs config.config property for inline translation + * Create a view asset representing the RequireJS config.config property for inline translation. * * @return \Magento\Framework\View\Asset\File */ @@ -65,7 +74,7 @@ public function createTranslateConfigAsset() } /** - * Gets current js-translation.json timestamp + * Get current js-translation.json timestamp. * * @return string|void */ @@ -81,7 +90,7 @@ public function getTranslationFileTimestamp() } /** - * Retrieve full path for translation file + * Retrieve full path for translation file. * * @return string */ @@ -95,7 +104,7 @@ protected function getTranslationFileFullPath() } /** - * Retrieve path for translation file + * Retrieve path for translation file. * * @return string */ @@ -105,10 +114,9 @@ public function getTranslationFilePath() } /** - * Update translation file with content - * - * @param string $content + * Update translation file with content. * + * @param array $content * @return void */ public function updateTranslationFileContent($content) @@ -119,9 +127,18 @@ public function updateTranslationFileContent($content) if (!$this->driverFile->isExists($this->getTranslationFileFullPath())) { $this->driverFile->createDirectory($translationDir); + $originalFileContent = ''; + } else { + $originalFileContent = $this->driverFile->fileGetContents($this->getTranslationFileFullPath()); } - - $this->driverFile->filePutContents($this->getTranslationFileFullPath(), $content); + $originalFileTranslationPhrases = !empty($originalFileContent) + ? $this->serializer->unserialize($originalFileContent) + : []; + $updatedTranslationPhrases = array_merge($originalFileTranslationPhrases, $content); + $this->driverFile->filePutContents( + $this->getTranslationFileFullPath(), + $this->serializer->serialize($updatedTranslationPhrases) + ); } /** diff --git a/app/code/Magento/Translation/Model/Inline/CacheManager.php b/app/code/Magento/Translation/Model/Inline/CacheManager.php index 712787498b96d..2002e9a73ec38 100644 --- a/app/code/Magento/Translation/Model/Inline/CacheManager.php +++ b/app/code/Magento/Translation/Model/Inline/CacheManager.php @@ -52,7 +52,7 @@ public function __construct( } /** - * Clears cache and updates translations file + * Clear cache and update translations file. * * @return array */ @@ -60,7 +60,8 @@ public function updateAndGetTranslations() { $this->eventManager->dispatch('adminhtml_cache_flush_system'); $translations = $this->translateResource->getTranslationArray(null, $this->localeResolver->getLocale()); - $this->fileManager->updateTranslationFileContent(json_encode($translations)); + $this->fileManager->updateTranslationFileContent($translations); + return $translations; } } diff --git a/app/code/Magento/Translation/Model/Inline/Renderer.php b/app/code/Magento/Translation/Model/Inline/Renderer.php new file mode 100644 index 0000000000000..b4ef2647ea352 --- /dev/null +++ b/app/code/Magento/Translation/Model/Inline/Renderer.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Translation\Model\Inline; + +use Magento\Framework\Phrase\RendererInterface; + +/** + * Inline Translate phrase renderer for DataProvider. + */ +class Renderer implements RendererInterface +{ + /** + * @inheritdoc + */ + public function render(array $source, array $arguments) + { + return end($source); + } +} diff --git a/app/code/Magento/Translation/Test/Mftf/ActionGroup/AdminTranslateElementActionGroup.xml b/app/code/Magento/Translation/Test/Mftf/ActionGroup/AdminTranslateElementActionGroup.xml index ed6b0c6b91b26..6db6e10dcce0d 100644 --- a/app/code/Magento/Translation/Test/Mftf/ActionGroup/AdminTranslateElementActionGroup.xml +++ b/app/code/Magento/Translation/Test/Mftf/ActionGroup/AdminTranslateElementActionGroup.xml @@ -8,12 +8,12 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminTranslateElementActionGroup"> + <actionGroup name="AdminTranslateElementActionGroup" deprecated="Avoid using super-ActionGroups. Use StorefrontOpenInlineTranslationPopupActionGroup, StorefrontFillCustomTranslationFieldActionGroup and StorefrontSubmitInlineTranslationFormActionGroup"> <arguments> <argument name="elementSelector" type="string"/> <argument name="translateText" type="string"/> </arguments> - + <executeJS function="jQuery('{{elementSelector}}').mousemove()" stepKey="moveMouseOverSelector"/> <executeJS function="jQuery('{{InlineTranslationModeSection.bookIcon}}').click()" stepKey="clickBookIcon"/> <waitForPageLoad stepKey="waitForLoadWindow"/> @@ -23,4 +23,4 @@ <fillField userInput="{{translateText}}" selector="{{InlineTranslationModeSection.inputCustomTranslate}}" stepKey="addTranslate"/> <click selector="{{InlineTranslationModeSection.buttonSubmit}}" stepKey="clickSubmitButton"/> </actionGroup> -</actionGroups> \ No newline at end of file +</actionGroups> diff --git a/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontFillCustomTranslationFieldActionGroup.xml b/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontFillCustomTranslationFieldActionGroup.xml new file mode 100644 index 0000000000000..e0e7072c2172a --- /dev/null +++ b/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontFillCustomTranslationFieldActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontFillCustomTranslationFieldActionGroup"> + <annotations> + <description>Fill the field in the Inline Translation form by provided text on Storefront.</description> + </annotations> + <arguments> + <argument name="translateText" type="string" defaultValue="Translated"/> + </arguments> + + <clearField selector="{{InlineTranslationModeSection.inputCustomTranslate}}" stepKey="clearCustomTranslateField"/> + <fillField selector="{{InlineTranslationModeSection.inputCustomTranslate}}" userInput="{{translateText}}" stepKey="fillCustomTranslateField"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontOpenInlineTranslationPopupActionGroup.xml b/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontOpenInlineTranslationPopupActionGroup.xml new file mode 100644 index 0000000000000..aa92fba7a8722 --- /dev/null +++ b/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontOpenInlineTranslationPopupActionGroup.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontOpenInlineTranslationPopupActionGroup"> + <annotations> + <description>Open the Inline Translation popup for provided element on Storefront.</description> + </annotations> + <arguments> + <argument name="elementSelector" type="string" defaultValue="{{StorefrontHeaderSection.welcomeMessage}}"/> + </arguments> + + <executeJS function="jQuery('{{elementSelector}}').mousemove()" stepKey="moveMouseOverSelector"/> + <executeJS function="jQuery('{{InlineTranslationModeSection.bookIcon}}').click()" stepKey="clickBookIcon"/> + <waitForElementVisible selector="{{InlineTranslationModeSection.popUpTranslate}}" stepKey="waitForTranslationPopupAppear"/> + <seeElement selector="{{InlineTranslationModeSection.popUpTranslate}}" stepKey="seeTranslateForm"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontSubmitInlineTranslationFormActionGroup.xml b/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontSubmitInlineTranslationFormActionGroup.xml new file mode 100644 index 0000000000000..280e356d87bcc --- /dev/null +++ b/app/code/Magento/Translation/Test/Mftf/ActionGroup/StorefrontSubmitInlineTranslationFormActionGroup.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontSubmitInlineTranslationFormActionGroup"> + <annotations> + <description>Click on the Inline Translation form submit button on Storefront.</description> + </annotations> + + <click selector="{{InlineTranslationModeSection.buttonSubmit}}" stepKey="clickSubmitButton"/> + <waitForElementNotVisible selector="{{InlineTranslationModeSection.popUpTranslate}}" stepKey="waitForTranslationPopupDisappear"/> + <dontSeeElement selector="{{InlineTranslationModeSection.popUpTranslate}}" stepKey="dontSeeTranslateForm"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Translation/Test/Mftf/Test/AdminInlineTranslationOnCheckoutTest.xml b/app/code/Magento/Translation/Test/Mftf/Test/AdminInlineTranslationOnCheckoutTest.xml index 7a107f059a84a..ad0cf1a5a1bc2 100644 --- a/app/code/Magento/Translation/Test/Mftf/Test/AdminInlineTranslationOnCheckoutTest.xml +++ b/app/code/Magento/Translation/Test/Mftf/Test/AdminInlineTranslationOnCheckoutTest.xml @@ -17,6 +17,9 @@ <testCaseId value="MC-11505"/> <group value="translation"/> <group value="checkout"/> + <skip> + <issueId value="MC-31663"/> + </skip> </annotations> <before> <actionGroup ref="AdminLoginActionGroup" stepKey="LoginAsAdmin"/> diff --git a/app/code/Magento/Translation/Test/Mftf/Test/StorefrontButtonsInlineTranslationTest.xml b/app/code/Magento/Translation/Test/Mftf/Test/StorefrontButtonsInlineTranslationTest.xml index d87d3635fa07c..1ba3236185148 100644 --- a/app/code/Magento/Translation/Test/Mftf/Test/StorefrontButtonsInlineTranslationTest.xml +++ b/app/code/Magento/Translation/Test/Mftf/Test/StorefrontButtonsInlineTranslationTest.xml @@ -12,57 +12,52 @@ <annotations> <features value="Translation"/> <stories value="Inline Translation"/> - <title value="[Inline Translation] Buttons inline translation"/> - <description value="[Inline Translation] Buttons inline translation"/> + <title value="Buttons inline translation"/> + <description value="A merchant should be able to translate buttons by an inline translation tool"/> <severity value="CRITICAL"/> - <testCaseId value="MC-12735"/> + <testCaseId value="MC-27118"/> + <useCaseId value="MC-24186"/> <group value="translation"/> - <skip> - <issueId value="MC-20127"/> - </skip> + <group value="catalog"/> + <group value="developer_mode_only"/> </annotations> <before> + <!-- Enable Translate Inline For Storefront --> + <magentoCLI command="config:set {{EnableTranslateInlineForStorefront.path}} {{EnableTranslateInlineForStorefront.value}}" stepKey="enableTranslateInlineForStorefront"/> + <!-- Create Category --> + <createData entity="ApiCategory" stepKey="createCategory"/> <!-- Create Simple Product --> - <createData entity="SimpleProduct2" stepKey="createProduct"/> - <!-- Enable Translate Inline For Storefront--> - <magentoCLI - command="config:set {{EnableTranslateInlineForStorefront.path}} {{EnableTranslateInlineForStorefront.value}}" - stepKey="enableTranslateInlineForStorefront"/> - <!-- Set developer mode --> - <magentoCLI command="deploy:mode:set developer" stepKey="setDeveloperMode"/> - <magentoCLI command="cache:flush" stepKey="flushCache"/> + <createData entity="ApiSimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> </before> <after> <!-- Disable Translate Inline For Storefront --> - <magentoCLI - command="config:set {{DisableTranslateInlineForStorefront.path}} {{DisableTranslateInlineForStorefront.value}}" - stepKey="disableTranslateInlineForStorefront"/> - <!-- Set production mode --> - <magentoCLI command="deploy:mode:set production" stepKey="setProductionMode"/> - + <magentoCLI command="config:set {{DisableTranslateInlineForStorefront.path}} {{DisableTranslateInlineForStorefront.value}}" stepKey="disableTranslateInlineForStorefront"/> <!-- Delete Simple Product --> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <!-- Delete Category --> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> </after> <!-- Add product to cart on storefront --> - <actionGroup ref="AddSimpleProductToCartActionGroup" stepKey="addProductToCart"> - <argument name="product" value="$$createProduct$$"/> + <amOnPage url="{{StorefrontCategoryPage.url($createCategory.custom_attributes[url_key]$)}}" stepKey="goToCategoryPage"/> + <waitForPageLoad stepKey="waitForCategoryPageLoad"/> + <actionGroup ref="StorefrontAddProductToCartFromCategoryActionGroup" stepKey="addProductToCart"> + <argument name="productName" value="$createProduct.name$"/> </actionGroup> - <!-- Click on cart button on the top --> - <click selector="{{StorefrontMiniCartSection.show}}" stepKey="showMiniCart"/> - - <!-- Small cart popup appeared. --> - <waitForElementVisible selector="{{StorefrontMinicartSection.productName}}" stepKey="seeProductNameAppeared"/> + <!-- Open Mini Cart --> + <actionGroup ref="StorefrontOpenMiniCartActionGroup" stepKey="openMiniCart"/> <!-- Check button "Proceed to Checkout". There must be red borders and "book" icons on labels that can be translated. --> <actionGroup ref="AssertElementInTranslateInlineModeActionGroup" stepKey="assertRedBordersAndBookIcon"> <argument name="elementSelector" value="{{StorefrontMinicartSection.goToCheckout}}"/> </actionGroup> - <actionGroup ref="AdminTranslateElementActionGroup" stepKey="translateProceedToCheckoutButtonText"> + <!-- Open Inline Translation popup --> + <actionGroup ref="StorefrontOpenInlineTranslationPopupActionGroup" stepKey="openInlineTranslationPopup"> <argument name="elementSelector" value="{{StorefrontMinicartSection.goToCheckout}}"/> - <argument name="translateText" value="Proceed to Checkout Translated"/> </actionGroup> </test> </tests> diff --git a/app/code/Magento/Translation/Test/Unit/App/Config/Type/TranslationTest.php b/app/code/Magento/Translation/Test/Unit/App/Config/Type/TranslationTest.php index 6b262b9e9f93c..8759c9048fe0f 100644 --- a/app/code/Magento/Translation/Test/Unit/App/Config/Type/TranslationTest.php +++ b/app/code/Magento/Translation/Test/Unit/App/Config/Type/TranslationTest.php @@ -5,7 +5,6 @@ */ namespace Magento\Translation\Test\Unit\App\Config\Type; -use Magento\Authorizenet\Helper\Backend\Data; use Magento\Framework\App\Cache\Type\Translate; use Magento\Framework\App\Config\ConfigSourceInterface; use Magento\Framework\Cache\FrontendInterface; diff --git a/app/code/Magento/Translation/etc/di.xml b/app/code/Magento/Translation/etc/di.xml index 783384fe64fa9..f19eebd29ae11 100644 --- a/app/code/Magento/Translation/etc/di.xml +++ b/app/code/Magento/Translation/etc/di.xml @@ -49,6 +49,18 @@ </argument> </arguments> </type> + <virtualType name="dataProviderCompositeRenderer" type="Magento\Framework\Phrase\Renderer\Composite"> + <arguments> + <argument name="renderers" xsi:type="array"> + <item name="inline" xsi:type="object">Magento\Translation\Model\Inline\Renderer</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Translation\Model\Js\DataProvider"> + <arguments> + <argument name="translate" xsi:type="object">dataProviderCompositeRenderer</argument> + </arguments> + </type> <type name="Magento\Framework\Phrase\Renderer\Translate"> <arguments> <argument name="translator" xsi:type="object">Magento\Framework\Translate</argument> diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php index 586d76828ba3a..f1ff9db2dfde6 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php @@ -7,6 +7,7 @@ use Magento\Framework\Data\OptionSourceInterface; use Magento\Framework\View\Element\UiComponent\ContextInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer; /** * Base abstract form element. @@ -23,6 +24,11 @@ abstract class AbstractOptionsField extends AbstractElement */ protected $options; + /** + * @var Sanitizer + */ + private $sanitizer; + /** * Constructor * @@ -30,14 +36,17 @@ abstract class AbstractOptionsField extends AbstractElement * @param array|OptionSourceInterface|null $options * @param array $components * @param array $data + * @param Sanitizer|null $sanitizer */ public function __construct( ContextInterface $context, $options = null, array $components = [], - array $data = [] + array $data = [], + ?Sanitizer $sanitizer = null ) { $this->options = $options; + $this->sanitizer = $sanitizer ?? \Magento\Framework\App\ObjectManager::getInstance()->get(Sanitizer::class); parent::__construct($context, $components, $data); } @@ -62,13 +71,10 @@ public function prepare() if (empty($config['rawOptions'])) { $options = $this->convertOptionsValueToString($options); } - - array_walk( - $options, - function (&$item) { - $item['__disableTmpl'] = true; - } - ); + foreach ($options as &$option) { + //Options contain static or dynamic entity data that is not supposed to contain templates. + $option = $this->sanitizer->sanitize($option); + } $config['options'] = array_values(array_replace_recursive($config['options'], $options)); } diff --git a/app/code/Magento/Ui/Component/MassAction.php b/app/code/Magento/Ui/Component/MassAction.php index 5af263dd861ce..4cca8d4c012bb 100644 --- a/app/code/Magento/Ui/Component/MassAction.php +++ b/app/code/Magento/Ui/Component/MassAction.php @@ -28,7 +28,7 @@ public function prepare() if ($disabledAction) { continue; } - $config['actions'][] = array_merge($componentConfig, ['__disableTmpl' => true]); + $config['actions'][] = $componentConfig; } $origConfig = $this->getConfiguration(); diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminAssertGridNotEmptyActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminAssertGridNotEmptyActionGroup.xml new file mode 100644 index 0000000000000..7c951db99ef5e --- /dev/null +++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminAssertGridNotEmptyActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminAssertGridNotEmptyActionGroup"> + <waitForLoadingMaskToDisappear stepKey="waitForGridLoaded"/> + <dontSee selector="{{AdminDataGridTableSection.dataGridEmpty}}" userInput="We couldn't find any records." stepKey="expectNotEmptyGrid"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminUiGridSelectFilterOptionActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminUiGridSelectFilterOptionActionGroup.xml new file mode 100644 index 0000000000000..1c5a27ab326c3 --- /dev/null +++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/AdminUiGridSelectFilterOptionActionGroup.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminUiGridSelectFilterOptionActionGroup"> + <arguments> + <argument name="filterName" type="string"/> + <argument name="filterValue" type="string"/> + </arguments> + <selectOption selector="{{AdminDataGridFilterSection.selectByNameAttrInGrid(filterName)}}" userInput="{{filterValue}}" stepKey="selectOption"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminFormSaveAndCloseActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminFormSaveAndCloseActionGroup.xml deleted file mode 100644 index d712c1a116068..0000000000000 --- a/app/code/Magento/Ui/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminFormSaveAndCloseActionGroup.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminFormSaveAndClose"> - <annotations> - <description>Clicks on 'Save and Close'. Validates that the Success Message is present.</description> - </annotations> - - <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> - <click selector="{{AdminProductFormActionSection.saveAndClose}}" stepKey="clickOnSaveAndClose"/> - <seeElement selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveMessageSuccess"/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminFormSaveAndDuplicateActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminFormSaveAndDuplicateActionGroup.xml deleted file mode 100644 index 51031a7225889..0000000000000 --- a/app/code/Magento/Ui/Test/Mftf/ActionGroup/_Deprecated_ActionGroup/AdminFormSaveAndDuplicateActionGroup.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AdminFormSaveAndDuplicate"> - <annotations> - <description>Clicks on 'Save and Duplicate'. Validates that the Success Message is present and correct.</description> - </annotations> - - <click selector="{{AdminProductFormActionSection.saveArrow}}" stepKey="openSaveDropDown"/> - <click selector="{{AdminProductFormActionSection.saveAndDuplicate}}" stepKey="clickOnSaveAndDuplicate"/> - <see selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertSaveSuccess" userInput="You saved the product."/> - <see selector="{{AdminProductMessagesSection.successMessage}}" stepKey="assertDuplicateSuccess" userInput="You duplicated the product."/> - </actionGroup> -</actionGroups> diff --git a/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridFilterSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridFilterSection.xml index e93df2d26ffc4..ec4554be21510 100644 --- a/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridFilterSection.xml +++ b/app/code/Magento/Ui/Test/Mftf/Section/AdminDataGridFilterSection.xml @@ -13,6 +13,7 @@ <element name="filterExpand" type="button" selector="//div[@class='admin__data-grid-header'][(not(ancestor::*[@class='sticky-header']) and not(contains(@style,'visibility: hidden'))) or (ancestor::*[@class='sticky-header' and not(contains(@style,'display: none'))])]//button[@data-action='grid-filter-expand']" /> <element name="inputFieldByNameAttr" type="input" selector="//*[@data-part='filter-form']//input[@name='{{inputNameAttr}}']" parameterized="true" /> <element name="inputFieldByNameAttrInGrid" type="input" selector="//*[@data-role='filter-form']//input[@name='{{inputNameAttr}}']" parameterized="true"/> + <element name="selectByNameAttrInGrid" type="input" selector="//*[@data-role='filter-form']//select[@name='{{inputNameAttr}}']" parameterized="true"/> <element name="filterSelectFieldByName" type="select" selector="//*[@data-part='filter-form']//select[@name='{{fieldName}}']" parameterized="true"/> <element name="apply" type="button" selector="//*[@data-part='filter-form']//button[@data-action='grid-filter-apply']" /> <element name="clear" type="button" selector=".admin__data-grid-header [data-action='grid-filter-reset']" /> diff --git a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridFilterDeleteAndVerifyErrorMessageTest.xml b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridFilterDeleteAndVerifyErrorMessageTest.xml index 3cc120ad98176..d38e065914617 100644 --- a/app/code/Magento/Ui/Test/Mftf/Test/AdminGridFilterDeleteAndVerifyErrorMessageTest.xml +++ b/app/code/Magento/Ui/Test/Mftf/Test/AdminGridFilterDeleteAndVerifyErrorMessageTest.xml @@ -20,7 +20,7 @@ <before> <magentoCLI command="config:set system/backup/functionality_enabled 1" stepKey="setEnableBackupToYes"/> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> <createData entity="NewRootCategory" stepKey="rootCategory"/> <createData entity="defaultSimpleProduct" stepKey="createProduct"> <requiredEntity createDataKey="rootCategory" /> diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php index c2e064bb3b069..5922055328fc1 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php @@ -8,14 +8,15 @@ use Magento\Ui\Component\MassAction; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Element\UiComponent\ContextInterface; +use PHPUnit\Framework\MockObject\MockObject; /** - * Class MassActionTest + * Class MassAction test for Component */ class MassActionTest extends \PHPUnit\Framework\TestCase { /** - * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ContextInterface|MockObject */ protected $contextMock; @@ -105,7 +106,6 @@ public function getPrepareDataProvider() 'type' => 'first_action', 'label' => 'First Action', 'url' => '/module/controller/firstAction', - '__disableTmpl' => true ], ], [ @@ -125,7 +125,6 @@ public function getPrepareDataProvider() 'url' => '/module/controller/secondSubAction2' ], ], - '__disableTmpl' => true ], ], ]; diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js index 5667ce5d71d81..b488a4b2f8c16 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js @@ -1160,6 +1160,7 @@ define([ if (this.isSearchKeyCached(searchKey)) { cachedSearchResult = this.getCachedSearchResults(searchKey); + this.cacheOptions.plain = cachedSearchResult.options; this.options(cachedSearchResult.options); this.afterLoadOptions(searchKey, cachedSearchResult.lastPage, cachedSearchResult.total); @@ -1274,6 +1275,7 @@ define([ }); this.total = response.total; + this.cacheOptions.plain = existingOptions; this.options(existingOptions); }, diff --git a/app/code/Magento/Ui/view/base/web/js/modal/alert.js b/app/code/Magento/Ui/view/base/web/js/modal/alert.js index f36fe54a37a9e..0c7042952bc18 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/alert.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/alert.js @@ -39,18 +39,11 @@ define([ }] }, - /** - * Create widget. - */ - _create: function () { - this.options.actions.always(); - this._super(); - }, - /** * Close modal window. */ closeModal: function () { + this.options.actions.always(); this.element.bind('alertclosed', _.bind(this._remove, this)); return this._super(); diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddCustomUrlRewriteActionGroup.xml b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddCustomUrlRewriteActionGroup.xml index 5dcb97692d047..dbc5e4bd48e84 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddCustomUrlRewriteActionGroup.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddCustomUrlRewriteActionGroup.xml @@ -33,6 +33,6 @@ <click selector="{{AdminUrlRewriteEditSection.redirectTypeValue('redirectTypeValue')}}" stepKey="selectRedirectTypeValue"/> <fillField selector="{{AdminUrlRewriteEditSection.description}}" userInput="{{description}}" stepKey="fillDescription"/> <click selector="{{AdminUrlRewriteEditSection.saveButton}}" stepKey="clickOnSaveButton"/> - <seeElement selector="{{AdminMessagesSection.successMessage}}" stepKey="seeSuccessSaveMessage"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSuccessSaveMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteActionGroup.xml b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteActionGroup.xml index 1bb3e80aa06b7..b0335607d5455 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteActionGroup.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteActionGroup.xml @@ -35,6 +35,6 @@ <click selector="{{AdminUrlRewriteEditSection.redirectTypeValue('redirectTypeValue')}}" stepKey="clickOnRedirectTypeValue"/> <fillField selector="{{AdminUrlRewriteEditSection.description}}" userInput="{{description}}" stepKey="fillDescription"/> <click selector="{{AdminUrlRewriteEditSection.saveButton}}" stepKey="clickOnSaveButton"/> - <seeElement selector="{{AdminMessagesSection.successMessage}}" stepKey="seeSuccessSaveMessage"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSuccessSaveMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteForProductActionGroup.xml b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteForProductActionGroup.xml index 3a72c73f3e54a..f1dcf175455f3 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteForProductActionGroup.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminAddUrlRewriteForProductActionGroup.xml @@ -29,6 +29,6 @@ <click selector="{{AdminUrlRewriteEditSection.redirectTypeValue('redirectTypeValue')}}" stepKey="clickOnRedirectTypeValue"/> <fillField selector="{{AdminUrlRewriteEditSection.description}}" userInput="{{description}}" stepKey="fillDescription"/> <click selector="{{AdminUrlRewriteEditSection.saveButton}}" stepKey="clickOnSaveButton"/> - <seeElement selector="{{AdminMessagesSection.successMessage}}" stepKey="seeSuccessSaveMessage"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSuccessSaveMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminDeleteUrlRewriteActionGroup.xml b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminDeleteUrlRewriteActionGroup.xml index a5519e84b4c03..4d26f60cd48eb 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminDeleteUrlRewriteActionGroup.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminDeleteUrlRewriteActionGroup.xml @@ -32,6 +32,6 @@ <waitForElementVisible selector="{{AdminUrlRewriteEditSection.okButton}}" stepKey="waitForOkButtonToVisible"/> <click selector="{{AdminUrlRewriteEditSection.okButton}}" stepKey="clickOnOkButton"/> <waitForPageLoad stepKey="waitForPageToLoad3"/> - <see selector="{{AdminMessagesSection.successMessage}}" userInput="You deleted the URL rewrite." stepKey="seeSuccessMessage"/> + <see selector="{{AdminMessagesSection.success}}" userInput="You deleted the URL rewrite." stepKey="seeSuccessMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateCustomUrlRewriteActionGroup.xml b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateCustomUrlRewriteActionGroup.xml index 69b5906c9f6e1..ed60081160ace 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateCustomUrlRewriteActionGroup.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateCustomUrlRewriteActionGroup.xml @@ -27,6 +27,6 @@ <selectOption selector="{{AdminUrlRewriteEditSection.redirectType}}" userInput="{{redirectTypeValue}}" stepKey="selectRedirectTypeValue"/> <fillField selector="{{AdminUrlRewriteEditSection.description}}" userInput="{{description}}" stepKey="fillDescription"/> <click selector="{{AdminUrlRewriteEditSection.saveButton}}" stepKey="clickOnSaveButton"/> - <seeElement selector="{{AdminMessagesSection.successMessage}}" stepKey="seeSuccessSaveMessage"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSuccessSaveMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateUrlRewriteActionGroup.xml b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateUrlRewriteActionGroup.xml index 386836fe2da69..c3e539db34108 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateUrlRewriteActionGroup.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUpdateUrlRewriteActionGroup.xml @@ -26,6 +26,6 @@ <click selector="{{AdminUrlRewriteEditSection.redirectTypeValue(redirectTypeValue)}}" stepKey="selectRedirectTypeValue"/> <fillField selector="{{AdminUrlRewriteEditSection.description}}" userInput="{{description}}" stepKey="fillDescription"/> <click selector="{{AdminUrlRewriteEditSection.saveButton}}" stepKey="clickOnSaveButton"/> - <seeElement selector="{{AdminMessagesSection.successMessage}}" stepKey="seeSuccessSaveMessage"/> + <seeElement selector="{{AdminMessagesSection.success}}" stepKey="seeSuccessSaveMessage"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest.xml deleted file mode 100644 index 82849755d78fc..0000000000000 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest.xml +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategoryTest"> - <annotations> - <features value="Url Rewrite"/> - <stories value="Update url rewrites"/> - <title value="DEPRECATED. Check url rewrites in catalog categories after changing url key"/> - <description value="DEPRECATED. Check url rewrites in catalog categories after changing url key for store view and moving category"/> - <severity value="CRITICAL"/> - <testCaseId value="MC-5352"/> - <group value="url_rewrite"/> - <group value="mtf_migrated"/> - <skip> - <issueId value="DEPRECATED">Use AdminCheckUrlRewritesInCatalogCategoriesAfterChangingUrlKeyForStoreViewAndMovingCategory2Test instead</issueId> - </skip> - </annotations> - <before> - <!-- Create two sub-categories in default category with simple products --> - <createData entity="_defaultCategory" stepKey="createFirstCategory"/> - <createData entity="_defaultProduct" stepKey="createFirstSimpleProduct"> - <requiredEntity createDataKey="createFirstCategory"/> - </createData> - <createData entity="_defaultCategory" stepKey="createSecondCategory"/> - <createData entity="_defaultProduct" stepKey="createSecondSimpleProduct"> - <requiredEntity createDataKey="createSecondCategory"/> - </createData> - - <!-- Log in to backend --> - <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> - - <!--Create additional Store View in Main Website Store --> - <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView"/> - - <!-- Reindex and flush the cache --> - <magentoCLI command="indexer:reindex" stepKey="runReindex"/> - <magentoCLI command="cache:flush" stepKey="cleanCache"/> - </before> - <after> - <deleteData createDataKey="createFirstCategory" stepKey="deleteFirstCategory"/> - <deleteData createDataKey="createSecondCategory" stepKey="deleteSecondCategory"/> - <deleteData createDataKey="createFirstSimpleProduct" stepKey="deleteFirstSimpleProduct"/> - <deleteData createDataKey="createSecondSimpleProduct" stepKey="deleteSecondSimpleProduct"/> - <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteStoreView"/> - <actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/> - </after> - - <!-- On the categories editing page change store view to created additional view --> - <actionGroup ref="SwitchCategoryStoreViewActionGroup" stepKey="switchStoreView"> - <argument name="Store" value="customStore.name"/> - <argument name="CatName" value="$$createFirstCategory.name$$"/> - </actionGroup> - - <!-- Change url key for category for first category; save --> - <actionGroup ref="ChangeSeoUrlKeyForSubCategoryActionGroup" stepKey="changeUrlKey"> - <argument name="value" value="{{SimpleRootSubCategory.url_key}}"/> - </actionGroup> - - <!-- Change store view to "All store views" for first category --> - <actionGroup ref="SwitchCategoryToAllStoreViewActionGroup" stepKey="switchToAllStoreViewProduct"> - <argument name="CatName" value="$$createFirstCategory.name$$"/> - </actionGroup> - - <!-- Move first category inside second category --> - <actionGroup ref="MoveCategoryActionGroup" stepKey="moveFirstCategoryToSecondCategory"> - <argument name="childCategory" value="$$createFirstCategory.name$$"/> - <argument name="parentCategory" value="$$createSecondCategory.name$$"/> - </actionGroup> - - <!-- Switch default store view on store view created below for first category --> - <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="amOnStorefrontPage"/> - <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="storefrontSwitchStoreView"> - <argument name="storeView" value="customStore"/> - </actionGroup> - - <!-- Assert category url with custom store view --> - <amOnPage url="{{StorefrontHomePage.url}}$$createSecondCategory.name$$/{{SimpleRootSubCategory.url_key}}.html" stepKey="amOnCategoryPage"/> - <waitForPageLoad stepKey="waitForCategoryPageLoad"/> - <see userInput="$$createFirstSimpleProduct.name$$" selector="{{StorefrontCategoryMainSection.productsList}}" stepKey="seeProductInCategory"/> - </test> -</tests> diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductWithSeveralWebsitesAndCheckURLRewritesTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductWithSeveralWebsitesAndCheckURLRewritesTest.xml index 653995da1a3a8..036d35d9c3258 100644 --- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductWithSeveralWebsitesAndCheckURLRewritesTest.xml +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminCreateProductWithSeveralWebsitesAndCheckURLRewritesTest.xml @@ -24,7 +24,7 @@ <requiredEntity createDataKey="rootCategory"/> </createData> <createData entity="defaultSimpleProduct" stepKey="createProduct"/> - <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/> </before> <after> <actionGroup ref="DeleteCustomStoreActionGroup" stepKey="deleteStore1"> diff --git a/app/code/Magento/User/Test/Mftf/Test/AdminUpdateUserTest.xml b/app/code/Magento/User/Test/Mftf/Test/AdminUpdateUserTest.xml index d1034c7a5945f..10f81c9254b40 100644 --- a/app/code/Magento/User/Test/Mftf/Test/AdminUpdateUserTest.xml +++ b/app/code/Magento/User/Test/Mftf/Test/AdminUpdateUserTest.xml @@ -72,7 +72,8 @@ </actionGroup> <actionGroup ref="AdminLogoutActionGroup" stepKey="logOutFromAdminPanel"/> <actionGroup ref="AdminLoginActionGroup" stepKey="loginAsSaleRoleUser"> - <argument name="adminUser" value="AdminUserWithUpdatedUserRoleToSales"/> + <argument name="username" value="{{AdminUserWithUpdatedUserRoleToSales.username}}"/> + <argument name="password" value="{{AdminUserWithUpdatedUserRoleToSales.password}}"/> </actionGroup> <actionGroup ref="AssertAdminSuccessLoginActionGroup" stepKey="seeSuccessloginMessage"/> <actionGroup ref="AdminOpenAdminUsersPageActionGroup" stepKey="navigateToAdminUsersPage"/> diff --git a/app/code/Magento/WebapiAsync/composer.json b/app/code/Magento/WebapiAsync/composer.json index d076897d61e2e..b37b5de12ca0d 100644 --- a/app/code/Magento/WebapiAsync/composer.json +++ b/app/code/Magento/WebapiAsync/composer.json @@ -7,6 +7,7 @@ "require": { "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", + "magento/framework-message-queue": "*", "magento/module-webapi": "*", "magento/module-asynchronous-operations": "*" }, diff --git a/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/_module.less index daed96db717c7..780abd250301a 100644 --- a/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_CatalogSearch/web/css/source/_module.less @@ -65,6 +65,7 @@ } input { + font-size: 16px; left: -300%; margin: 15px 0; position: absolute; diff --git a/app/design/frontend/Magento/luma/Magento_CatalogSearch/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_CatalogSearch/web/css/source/_module.less index 2176fcd241916..9a85e3a02712c 100644 --- a/app/design/frontend/Magento/luma/Magento_CatalogSearch/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_CatalogSearch/web/css/source/_module.less @@ -80,6 +80,7 @@ } input { + font-size: 16px; left: -300%; margin: 15px 0; position: absolute; diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new.html b/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new.html index 86e3cf01e965e..f8e192bafdf29 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new.html @@ -20,6 +20,8 @@ "var store_email":"Store Email", "var creditmemo":"Credit Memo", "var order":"Order", +"var order_id": "Order DB Id", +"var creditmemo_id": "Credit Memo DB Id", "var order_data.is_not_virtual":"Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -79,7 +81,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_creditmemo_items" creditmemo=$creditmemo order=$order}} + {{layout handle="sales_email_order_creditmemo_items" creditmemo_id=$creditmemo_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new_guest.html index d0310a8e2c7b6..4442c172a08e5 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new_guest.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/creditmemo_new_guest.html @@ -19,6 +19,8 @@ "var store_email":"Store Email", "var creditmemo":"Credit Memo", "var order":"Order", +"var order_id": "Order DB Id", +"var creditmemo_id": "Credit Memo DB Id", "var order_data.is_not_virtual":"Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -77,7 +79,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_creditmemo_items" creditmemo=$creditmemo order=$order}} + {{layout handle="sales_email_order_creditmemo_items" creditmemo_id=$creditmemo_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new.html b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new.html index 636fa9ac5f425..c46f0b03a53f7 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new.html @@ -20,6 +20,8 @@ "var store_email":"Store Email", "var invoice": "Invoice", "var order": "Order", +"var order_id": "Order DB Id", +"var invoice_id": "Invoice DB Id", "var order_data.is_not_virtual": "Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -79,7 +81,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout area="frontend" handle="sales_email_order_invoice_items" invoice=$invoice order=$order}} + {{layout area="frontend" handle="sales_email_order_invoice_items" invoice_id=$invoice_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new_guest.html index 7df5ffe5f4ab8..6e35fd2609dff 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new_guest.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_new_guest.html @@ -19,6 +19,8 @@ "var store_email":"Store Email", "var invoice": "Invoice", "var order": "Order", +"var order_id": "Order DB Id", +"var invoice_id": "Invoice DB Id", "var order_data.is_not_virtual": "Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -77,7 +79,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_invoice_items" invoice=$invoice order=$order}} + {{layout handle="sales_email_order_invoice_items" invoice_id=$invoice_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/order_new.html b/app/design/frontend/Magento/luma/Magento_Sales/email/order_new.html index 745bf5c9c2eff..373db99d87d99 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/order_new.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/order_new.html @@ -20,6 +20,7 @@ "var order":"Order", "var order_data.is_not_virtual":"Order Type", "var order_data.customer_name":"Customer Name", +"var order_id": "Order DB Id", "var this.getUrl($store,'customer/account/',[_nosid:1])":"Customer Account URL" } @--> @@ -85,7 +86,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_items" order=$order area="frontend"}} + {{layout handle="sales_email_order_items" order_id=$order_id area="frontend"}} </td> </tr> </table> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/order_new_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/order_new_guest.html index 907be4d45a6c5..024f6daf76ace 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/order_new_guest.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/order_new_guest.html @@ -19,6 +19,7 @@ "var store.frontend_name":"Store Frontend Name", "var store_email":"Store Email", "var order":"Order", +"var order_id": "Order DB Id", "var order_data.is_not_virtual":"Order Type" } @--> {{template config_path="design/email/header_template"}} @@ -82,7 +83,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_items" order=$order}} + {{layout handle="sales_email_order_items" order_id=$order_id}} </td> </tr> </table> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new.html b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new.html index 4ff9da3a31b27..d1b1e1e33763c 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new.html @@ -21,7 +21,9 @@ "var store_email":"Store Email", "var order_data.is_not_virtual": "Order Type", "var shipment": "Shipment", -"var order": "Order" +"var order": "Order", +"var order_id": "Order DB Id", +"var shipment_id": "Shipment DB Id" } @--> {{template config_path="design/email/header_template"}} @@ -55,7 +57,7 @@ <h1>{{trans "Your Shipment #%shipment_id for Order #%order_id" shipment_id=$ship </tr> </table> {{/depend}} - {{layout handle="sales_email_order_shipment_track" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_track" shipment_id=$shipment_id order_id=$order_id}} <table class="order-details"> <tr> <td class="address-details"> @@ -82,7 +84,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_items" shipment_id=$shipment_id order_id=$order_id}} </td> </tr> </table> diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html index ac7eaae6b7ff7..18684fb052b4e 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_new_guest.html @@ -21,6 +21,8 @@ "var order_data.is_not_virtual": "Order Type", "var shipment": "Shipment", "var order": "Order", +"var order_id": "Order DB Id", +"var shipment_id": "Shipment DB Id", "var this.getUrl($store,'customer/account/',[_nosid:1])":"Customer Account URL" } @--> {{template config_path="design/email/header_template"}} @@ -54,7 +56,7 @@ <h1>{{trans "Your Shipment #%shipment_id for Order #%order_id" shipment_id=$ship </tr> </table> {{/depend}} - {{layout handle="sales_email_order_shipment_track" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_track" shipment_id=$shipment_id order_id=$order_id}} <table class="order-details"> <tr> <td class="address-details"> @@ -81,7 +83,7 @@ <h3>{{trans "Shipping Method"}}</h3> {{/depend}} </tr> </table> - {{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}} + {{layout handle="sales_email_order_shipment_items" shipment_id=$shipment_id order_id=$order_id}} </td> </tr> </table> diff --git a/composer.json b/composer.json index 769885ef305bf..2a19802e4fb2a 100644 --- a/composer.json +++ b/composer.json @@ -111,10 +111,6 @@ "magento/module-analytics": "*", "magento/module-asynchronous-operations": "*", "magento/module-authorization": "*", - "magento/module-authorizenet": "*", - "magento/module-authorizenet-acceptjs": "*", - "magento/module-authorizenet-cardinal": "*", - "magento/module-authorizenet-graph-ql": "*", "magento/module-advanced-search": "*", "magento/module-backend": "*", "magento/module-backup": "*", @@ -197,8 +193,13 @@ "magento/module-instant-purchase": "*", "magento/module-integration": "*", "magento/module-layered-navigation": "*", + "magento/module-media-content": "*", + "magento/module-media-content-api": "*", + "magento/module-media-content-catalog": "*", + "magento/module-media-content-cms": "*", "magento/module-media-gallery": "*", "magento/module-media-gallery-api": "*", + "magento/module-media-gallery-catalog": "*", "magento/module-media-storage": "*", "magento/module-message-queue": "*", "magento/module-msrp": "*", diff --git a/composer.lock b/composer.lock index 550de1d904aec..f1095dc95b150 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b801d92bd57ad3f2d51d2b264e9c37ac", + "content-hash": "b7ee4a27d76ea68e295d5025c986854d", "packages": [ { "name": "braintree/braintree_php", @@ -201,16 +201,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.2.6", + "version": "1.2.7", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "47fe531de31fca4a1b997f87308e7d7804348f7e" + "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/47fe531de31fca4a1b997f87308e7d7804348f7e", - "reference": "47fe531de31fca4a1b997f87308e7d7804348f7e", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/95c63ab2117a72f48f5a55da9740a3273d45b7fd", + "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd", "shasum": "" }, "require": { @@ -253,20 +253,30 @@ "ssl", "tls" ], - "time": "2020-01-13T10:02:55+00:00" + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-04-08T08:27:21+00:00" }, { "name": "composer/composer", - "version": "1.10.1", + "version": "1.10.5", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "b912a45da3e2b22f5cb5a23e441b697a295ba011" + "reference": "7a4d5b6aa30d2118af27c04f5e897b57156ccfa9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/b912a45da3e2b22f5cb5a23e441b697a295ba011", - "reference": "b912a45da3e2b22f5cb5a23e441b697a295ba011", + "url": "https://api.github.com/repos/composer/composer/zipball/7a4d5b6aa30d2118af27c04f5e897b57156ccfa9", + "reference": "7a4d5b6aa30d2118af27c04f5e897b57156ccfa9", "shasum": "" }, "require": { @@ -333,7 +343,7 @@ "dependency", "package" ], - "time": "2020-03-13T19:34:27+00:00" + "time": "2020-04-10T09:44:22+00:00" }, { "name": "composer/semver", @@ -698,23 +708,24 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.2", + "version": "6.5.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "43ece0e75098b7ecd8d13918293029e555a50f82" + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", - "reference": "43ece0e75098b7ecd8d13918293029e555a50f82", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aab4ebd862aa7d04f01a4b51849d657db56d882e", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.6.1", - "php": ">=5.5" + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.11" }, "require-dev": { "ext-curl": "*", @@ -722,7 +733,6 @@ "psr/log": "^1.1" }, "suggest": { - "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", @@ -761,7 +771,7 @@ "rest", "web service" ], - "time": "2019-12-23T11:57:10+00:00" + "time": "2020-04-18T10:38:46+00:00" }, { "name": "guzzlehttp/promises", @@ -1243,16 +1253,16 @@ }, { "name": "laminas/laminas-db", - "version": "2.11.2", + "version": "2.11.3", "source": { "type": "git", "url": "https://github.com/laminas/laminas-db.git", - "reference": "76f9527da996c2fef32ef1f3a939e18ca5e9d962" + "reference": "6c4238918b9204db1eb8cafae2c1940d40f4c007" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-db/zipball/76f9527da996c2fef32ef1f3a939e18ca5e9d962", - "reference": "76f9527da996c2fef32ef1f3a939e18ca5e9d962", + "url": "https://api.github.com/repos/laminas/laminas-db/zipball/6c4238918b9204db1eb8cafae2c1940d40f4c007", + "reference": "6c4238918b9204db1eb8cafae2c1940d40f4c007", "shasum": "" }, "require": { @@ -1261,7 +1271,7 @@ "php": "^5.6 || ^7.0" }, "replace": { - "zendframework/zend-db": "self.version" + "zendframework/zend-db": "^2.11.0" }, "require-dev": { "laminas/laminas-coding-standard": "~1.0.0", @@ -1301,7 +1311,7 @@ "db", "laminas" ], - "time": "2020-01-14T13:07:26+00:00" + "time": "2020-03-29T12:08:51+00:00" }, { "name": "laminas/laminas-dependency-plugin", @@ -1402,16 +1412,16 @@ }, { "name": "laminas/laminas-diactoros", - "version": "1.8.7p1", + "version": "1.8.7p2", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "56a9aca1f89231763d24d2ae13531b97fa5f4029" + "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/56a9aca1f89231763d24d2ae13531b97fa5f4029", - "reference": "56a9aca1f89231763d24d2ae13531b97fa5f4029", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6991c1af7c8d2c8efee81b22ba97024781824aaa", + "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa", "shasum": "" }, "require": { @@ -1423,7 +1433,7 @@ "psr/http-message-implementation": "1.0" }, "replace": { - "zendframework/zend-diactoros": "self.version" + "zendframework/zend-diactoros": "~1.8.7.0" }, "require-dev": { "ext-dom": "*", @@ -1473,7 +1483,7 @@ "psr", "psr-7" ], - "time": "2020-01-07T19:25:17+00:00" + "time": "2020-03-23T15:28:28+00:00" }, { "name": "laminas/laminas-escaper", @@ -1584,16 +1594,16 @@ }, { "name": "laminas/laminas-feed", - "version": "2.12.1", + "version": "2.12.2", "source": { "type": "git", "url": "https://github.com/laminas/laminas-feed.git", - "reference": "c9356994eb80d0f6b46d7e12ba048d450bf0cd72" + "reference": "8a193ac96ebcb3e16b6ee754ac2a889eefacb654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-feed/zipball/c9356994eb80d0f6b46d7e12ba048d450bf0cd72", - "reference": "c9356994eb80d0f6b46d7e12ba048d450bf0cd72", + "url": "https://api.github.com/repos/laminas/laminas-feed/zipball/8a193ac96ebcb3e16b6ee754ac2a889eefacb654", + "reference": "8a193ac96ebcb3e16b6ee754ac2a889eefacb654", "shasum": "" }, "require": { @@ -1605,7 +1615,7 @@ "php": "^5.6 || ^7.0" }, "replace": { - "zendframework/zend-feed": "self.version" + "zendframework/zend-feed": "^2.12.0" }, "require-dev": { "laminas/laminas-cache": "^2.7.2", @@ -1647,20 +1657,20 @@ "feed", "laminas" ], - "time": "2020-03-23T10:40:31+00:00" + "time": "2020-03-29T12:36:29+00:00" }, { "name": "laminas/laminas-filter", - "version": "2.9.3", + "version": "2.9.4", "source": { "type": "git", "url": "https://github.com/laminas/laminas-filter.git", - "reference": "52b5cdbef8902280996e687e7352a648a8e22f31" + "reference": "3c4476e772a062cef7531c6793377ae585d89c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-filter/zipball/52b5cdbef8902280996e687e7352a648a8e22f31", - "reference": "52b5cdbef8902280996e687e7352a648a8e22f31", + "url": "https://api.github.com/repos/laminas/laminas-filter/zipball/3c4476e772a062cef7531c6793377ae585d89c82", + "reference": "3c4476e772a062cef7531c6793377ae585d89c82", "shasum": "" }, "require": { @@ -1672,7 +1682,7 @@ "laminas/laminas-validator": "<2.10.1" }, "replace": { - "zendframework/zend-filter": "self.version" + "zendframework/zend-filter": "^2.9.2" }, "require-dev": { "laminas/laminas-coding-standard": "~1.0.0", @@ -1716,20 +1726,20 @@ "filter", "laminas" ], - "time": "2020-01-07T20:43:53+00:00" + "time": "2020-03-29T12:41:29+00:00" }, { "name": "laminas/laminas-form", - "version": "2.14.4", + "version": "2.14.5", "source": { "type": "git", "url": "https://github.com/laminas/laminas-form.git", - "reference": "8b985f74bfe32910edb4ba9503877c4310228cd2" + "reference": "3e22e09751cf6ae031be87a44e092e7925ce5b7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-form/zipball/8b985f74bfe32910edb4ba9503877c4310228cd2", - "reference": "8b985f74bfe32910edb4ba9503877c4310228cd2", + "url": "https://api.github.com/repos/laminas/laminas-form/zipball/3e22e09751cf6ae031be87a44e092e7925ce5b7b", + "reference": "3e22e09751cf6ae031be87a44e092e7925ce5b7b", "shasum": "" }, "require": { @@ -1740,7 +1750,7 @@ "php": "^5.6 || ^7.0" }, "replace": { - "zendframework/zend-form": "self.version" + "zendframework/zend-form": "^2.14.3" }, "require-dev": { "doctrine/annotations": "~1.0", @@ -1798,7 +1808,7 @@ "form", "laminas" ], - "time": "2020-03-18T22:38:54+00:00" + "time": "2020-03-29T12:46:16+00:00" }, { "name": "laminas/laminas-http", @@ -1924,16 +1934,16 @@ }, { "name": "laminas/laminas-i18n", - "version": "2.10.2", + "version": "2.10.3", "source": { "type": "git", "url": "https://github.com/laminas/laminas-i18n.git", - "reference": "9699c98d97d2f519def3da8d4128dfe6e6ad11bf" + "reference": "94ff957a1366f5be94f3d3a9b89b50386649e3ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-i18n/zipball/9699c98d97d2f519def3da8d4128dfe6e6ad11bf", - "reference": "9699c98d97d2f519def3da8d4128dfe6e6ad11bf", + "url": "https://api.github.com/repos/laminas/laminas-i18n/zipball/94ff957a1366f5be94f3d3a9b89b50386649e3ae", + "reference": "94ff957a1366f5be94f3d3a9b89b50386649e3ae", "shasum": "" }, "require": { @@ -1946,7 +1956,7 @@ "phpspec/prophecy": "<1.9.0" }, "replace": { - "zendframework/zend-i18n": "self.version" + "zendframework/zend-i18n": "^2.10.1" }, "require-dev": { "laminas/laminas-cache": "^2.6.1", @@ -1995,7 +2005,7 @@ "i18n", "laminas" ], - "time": "2020-03-20T11:57:14+00:00" + "time": "2020-03-29T12:51:08+00:00" }, { "name": "laminas/laminas-inputfilter", @@ -2362,16 +2372,16 @@ }, { "name": "laminas/laminas-mime", - "version": "2.7.3", + "version": "2.7.4", "source": { "type": "git", "url": "https://github.com/laminas/laminas-mime.git", - "reference": "e844abb02e868fae154207929190292ad25057cc" + "reference": "e45a7d856bf7b4a7b5bd00d6371f9961dc233add" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mime/zipball/e844abb02e868fae154207929190292ad25057cc", - "reference": "e844abb02e868fae154207929190292ad25057cc", + "url": "https://api.github.com/repos/laminas/laminas-mime/zipball/e45a7d856bf7b4a7b5bd00d6371f9961dc233add", + "reference": "e45a7d856bf7b4a7b5bd00d6371f9961dc233add", "shasum": "" }, "require": { @@ -2380,7 +2390,7 @@ "php": "^5.6 || ^7.0" }, "replace": { - "zendframework/zend-mime": "self.version" + "zendframework/zend-mime": "^2.7.2" }, "require-dev": { "laminas/laminas-coding-standard": "~1.0.0", @@ -2412,7 +2422,7 @@ "laminas", "mime" ], - "time": "2020-03-06T08:38:03+00:00" + "time": "2020-03-29T13:12:07+00:00" }, { "name": "laminas/laminas-modulemanager", @@ -2797,16 +2807,16 @@ }, { "name": "laminas/laminas-session", - "version": "2.9.2", + "version": "2.9.3", "source": { "type": "git", "url": "https://github.com/laminas/laminas-session.git", - "reference": "fdba34c1b257235dba2fff6ed4df1844390f85f6" + "reference": "519e8966146536cd97c1cc3d59a21b095fb814d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-session/zipball/fdba34c1b257235dba2fff6ed4df1844390f85f6", - "reference": "fdba34c1b257235dba2fff6ed4df1844390f85f6", + "url": "https://api.github.com/repos/laminas/laminas-session/zipball/519e8966146536cd97c1cc3d59a21b095fb814d7", + "reference": "519e8966146536cd97c1cc3d59a21b095fb814d7", "shasum": "" }, "require": { @@ -2816,7 +2826,7 @@ "php": "^5.6 || ^7.0" }, "replace": { - "zendframework/zend-session": "self.version" + "zendframework/zend-session": "^2.9.1" }, "require-dev": { "container-interop/container-interop": "^1.1", @@ -2864,7 +2874,7 @@ "laminas", "session" ], - "time": "2020-03-06T09:44:45+00:00" + "time": "2020-03-29T13:26:04+00:00" }, { "name": "laminas/laminas-soap", @@ -3078,16 +3088,16 @@ }, { "name": "laminas/laminas-validator", - "version": "2.13.2", + "version": "2.13.4", "source": { "type": "git", "url": "https://github.com/laminas/laminas-validator.git", - "reference": "e7bf6a2eedc0508ebde0ebc66662efeb0abbcb2c" + "reference": "93593684e70b8ed1e870cacd34ca32b0c0ace185" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/e7bf6a2eedc0508ebde0ebc66662efeb0abbcb2c", - "reference": "e7bf6a2eedc0508ebde0ebc66662efeb0abbcb2c", + "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/93593684e70b8ed1e870cacd34ca32b0c0ace185", + "reference": "93593684e70b8ed1e870cacd34ca32b0c0ace185", "shasum": "" }, "require": { @@ -3097,7 +3107,7 @@ "php": "^7.1" }, "replace": { - "zendframework/zend-validator": "self.version" + "zendframework/zend-validator": "^2.13.0" }, "require-dev": { "laminas/laminas-cache": "^2.6.1", @@ -3153,7 +3163,7 @@ "laminas", "validator" ], - "time": "2020-03-16T11:38:27+00:00" + "time": "2020-03-31T18:57:01+00:00" }, { "name": "laminas/laminas-view", @@ -3248,16 +3258,16 @@ }, { "name": "laminas/laminas-zendframework-bridge", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/laminas/laminas-zendframework-bridge.git", - "reference": "faf68f6109ceeff24241226033ab59640c7eb63b" + "reference": "bfbbdb6c998d50dbf69d2187cb78a5f1fa36e1e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/faf68f6109ceeff24241226033ab59640c7eb63b", - "reference": "faf68f6109ceeff24241226033ab59640c7eb63b", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/bfbbdb6c998d50dbf69d2187cb78a5f1fa36e1e9", + "reference": "bfbbdb6c998d50dbf69d2187cb78a5f1fa36e1e9", "shasum": "" }, "require": { @@ -3296,7 +3306,7 @@ "laminas", "zf" ], - "time": "2020-03-26T16:07:12+00:00" + "time": "2020-04-03T16:01:00+00:00" }, { "name": "magento/composer", @@ -3863,16 +3873,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.26", + "version": "2.0.27", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "09655fcc1f8bab65727be036b28f6f20311c126c" + "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/09655fcc1f8bab65727be036b28f6f20311c126c", - "reference": "09655fcc1f8bab65727be036b28f6f20311c126c", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", + "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", "shasum": "" }, "require": { @@ -3951,7 +3961,7 @@ "x.509", "x509" ], - "time": "2020-03-13T04:15:39+00:00" + "time": "2020-04-04T23:17:33+00:00" }, { "name": "psr/container", @@ -4362,16 +4372,16 @@ }, { "name": "symfony/console", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "4fa15ae7be74e53f6ec8c83ed403b97e23b665e9" + "reference": "10bb3ee3c97308869d53b3e3d03f6ac23ff985f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/4fa15ae7be74e53f6ec8c83ed403b97e23b665e9", - "reference": "4fa15ae7be74e53f6ec8c83ed403b97e23b665e9", + "url": "https://api.github.com/repos/symfony/console/zipball/10bb3ee3c97308869d53b3e3d03f6ac23ff985f7", + "reference": "10bb3ee3c97308869d53b3e3d03f6ac23ff985f7", "shasum": "" }, "require": { @@ -4434,20 +4444,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2020-02-24T13:10:00+00:00" + "time": "2020-03-30T11:41:10+00:00" }, { "name": "symfony/css-selector", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "d0a6dd288fa8848dcc3d1f58b94de6a7cc5d2d22" + "reference": "afc26133a6fbdd4f8842e38893e0ee4685c7c94b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/d0a6dd288fa8848dcc3d1f58b94de6a7cc5d2d22", - "reference": "d0a6dd288fa8848dcc3d1f58b94de6a7cc5d2d22", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/afc26133a6fbdd4f8842e38893e0ee4685c7c94b", + "reference": "afc26133a6fbdd4f8842e38893e0ee4685c7c94b", "shasum": "" }, "require": { @@ -4487,20 +4497,34 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2020-02-04T09:01:01+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "4ad8e149799d3128621a3a1f70e92b9897a8930d" + "reference": "abc8e3618bfdb55e44c8c6a00abd333f831bbfed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4ad8e149799d3128621a3a1f70e92b9897a8930d", - "reference": "4ad8e149799d3128621a3a1f70e92b9897a8930d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/abc8e3618bfdb55e44c8c6a00abd333f831bbfed", + "reference": "abc8e3618bfdb55e44c8c6a00abd333f831bbfed", "shasum": "" }, "require": { @@ -4557,7 +4581,21 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2020-02-04T09:32:40+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -4619,16 +4657,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "266c9540b475f26122b61ef8b23dd9198f5d1cfd" + "reference": "fe297193bf2e6866ed900ed2d5869362768df6a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/266c9540b475f26122b61ef8b23dd9198f5d1cfd", - "reference": "266c9540b475f26122b61ef8b23dd9198f5d1cfd", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/fe297193bf2e6866ed900ed2d5869362768df6a7", + "reference": "fe297193bf2e6866ed900ed2d5869362768df6a7", "shasum": "" }, "require": { @@ -4665,20 +4703,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2020-01-21T08:20:44+00:00" + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/finder", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "ea69c129aed9fdeca781d4b77eb20b62cf5d5357" + "reference": "5729f943f9854c5781984ed4907bbb817735776b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ea69c129aed9fdeca781d4b77eb20b62cf5d5357", - "reference": "ea69c129aed9fdeca781d4b77eb20b62cf5d5357", + "url": "https://api.github.com/repos/symfony/finder/zipball/5729f943f9854c5781984ed4907bbb817735776b", + "reference": "5729f943f9854c5781984ed4907bbb817735776b", "shasum": "" }, "require": { @@ -4714,7 +4752,21 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2020-02-14T07:42:58+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4774,6 +4826,68 @@ ], "time": "2020-02-27T09:26:54+00:00" }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", + "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "time": "2020-03-09T19:04:49+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.15.0", @@ -4833,6 +4947,61 @@ ], "time": "2020-03-09T19:04:49+00:00" }, + { + "name": "symfony/polyfill-php72", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "37b0976c78b94856543260ce09b460a7bc852747" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747", + "reference": "37b0976c78b94856543260ce09b460a7bc852747", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2020-02-27T09:26:54+00:00" + }, { "name": "symfony/polyfill-php73", "version": "v1.15.0", @@ -4893,16 +5062,16 @@ }, { "name": "symfony/process", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "bf9166bac906c9e69fb7a11d94875e7ced97bcd7" + "reference": "3e40e87a20eaf83a1db825e1fa5097ae89042db3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/bf9166bac906c9e69fb7a11d94875e7ced97bcd7", - "reference": "bf9166bac906c9e69fb7a11d94875e7ced97bcd7", + "url": "https://api.github.com/repos/symfony/process/zipball/3e40e87a20eaf83a1db825e1fa5097ae89042db3", + "reference": "3e40e87a20eaf83a1db825e1fa5097ae89042db3", "shasum": "" }, "require": { @@ -4938,7 +5107,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2020-02-07T20:06:44+00:00" + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/service-contracts", @@ -5414,16 +5583,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.133.45", + "version": "3.134.8", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "928a23e2ee7e195a66f93d0758895e26958c3b7d" + "reference": "8a9b598a0ede2165be5988899dcebead6fcc4d41" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/928a23e2ee7e195a66f93d0758895e26958c3b7d", - "reference": "928a23e2ee7e195a66f93d0758895e26958c3b7d", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/8a9b598a0ede2165be5988899dcebead6fcc4d41", + "reference": "8a9b598a0ede2165be5988899dcebead6fcc4d41", "shasum": "" }, "require": { @@ -5494,7 +5663,7 @@ "s3", "sdk" ], - "time": "2020-03-26T18:12:15+00:00" + "time": "2020-04-17T18:11:57+00:00" }, { "name": "behat/gherkin", @@ -5969,20 +6138,21 @@ }, { "name": "doctrine/annotations", - "version": "v1.8.0", + "version": "1.10.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc" + "reference": "5eb79f3dbdffed6544e1fc287572c0f462bd29bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/904dca4eb10715b92569fbcd79e201d5c349b6bc", - "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5eb79f3dbdffed6544e1fc287572c0f462bd29bb", + "reference": "5eb79f3dbdffed6544e1fc287572c0f462bd29bb", "shasum": "" }, "require": { "doctrine/lexer": "1.*", + "ext-tokenizer": "*", "php": "^7.1" }, "require-dev": { @@ -5992,7 +6162,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.9.x-dev" } }, "autoload": { @@ -6033,7 +6203,7 @@ "docblock", "parser" ], - "time": "2019-10-01T18:55:10+00:00" + "time": "2020-04-02T12:33:25+00:00" }, { "name": "doctrine/cache", @@ -6567,16 +6737,16 @@ }, { "name": "league/flysystem", - "version": "1.0.66", + "version": "1.0.67", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "021569195e15f8209b1c4bebb78bd66aa4f08c21" + "reference": "5b1f36c75c4bdde981294c2a0ebdb437ee6f275e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/021569195e15f8209b1c4bebb78bd66aa4f08c21", - "reference": "021569195e15f8209b1c4bebb78bd66aa4f08c21", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5b1f36c75c4bdde981294c2a0ebdb437ee6f275e", + "reference": "5b1f36c75c4bdde981294c2a0ebdb437ee6f275e", "shasum": "" }, "require": { @@ -6647,7 +6817,7 @@ "sftp", "storage" ], - "time": "2020-03-17T18:58:12+00:00" + "time": "2020-04-16T13:21:26+00:00" }, { "name": "lusitanian/oauth", @@ -8970,16 +9140,16 @@ }, { "name": "symfony/browser-kit", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "090ce406505149d6852a7c03b0346dec3b8cf612" + "reference": "e4b0dc1b100bf75b5717c5b451397f230a618a42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/090ce406505149d6852a7c03b0346dec3b8cf612", - "reference": "090ce406505149d6852a7c03b0346dec3b8cf612", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/e4b0dc1b100bf75b5717c5b451397f230a618a42", + "reference": "e4b0dc1b100bf75b5717c5b451397f230a618a42", "shasum": "" }, "require": { @@ -9025,20 +9195,34 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2020-02-23T10:00:59+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-28T10:15:50+00:00" }, { "name": "symfony/config", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "cbfef5ae91ccd3b06621c18d58cd355c68c87ae9" + "reference": "3f4a3de1af498ed0ea653d4dc2317794144e6ca4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/cbfef5ae91ccd3b06621c18d58cd355c68c87ae9", - "reference": "cbfef5ae91ccd3b06621c18d58cd355c68c87ae9", + "url": "https://api.github.com/repos/symfony/config/zipball/3f4a3de1af498ed0ea653d4dc2317794144e6ca4", + "reference": "3f4a3de1af498ed0ea653d4dc2317794144e6ca4", "shasum": "" }, "require": { @@ -9089,20 +9273,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2020-02-04T09:32:40+00:00" + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "ebb2e882e8c9e2eb990aa61ddcd389848466e342" + "reference": "755b18859be26b90f4bf63753432d3387458bf31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ebb2e882e8c9e2eb990aa61ddcd389848466e342", - "reference": "ebb2e882e8c9e2eb990aa61ddcd389848466e342", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/755b18859be26b90f4bf63753432d3387458bf31", + "reference": "755b18859be26b90f4bf63753432d3387458bf31", "shasum": "" }, "require": { @@ -9162,20 +9346,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2020-02-29T09:50:10+00:00" + "time": "2020-03-30T10:09:30+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "11dcf08f12f29981bf770f097a5d64d65bce5929" + "reference": "4d0fb3374324071ecdd94898367a3fa4b5563162" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/11dcf08f12f29981bf770f097a5d64d65bce5929", - "reference": "11dcf08f12f29981bf770f097a5d64d65bce5929", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4d0fb3374324071ecdd94898367a3fa4b5563162", + "reference": "4d0fb3374324071ecdd94898367a3fa4b5563162", "shasum": "" }, "require": { @@ -9223,20 +9407,34 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2020-02-29T10:05:28+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-29T19:12:22+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.0.5", + "version": "v5.0.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "6f9c2ba72f4295d7ce6cf9f79dbb18036291d335" + "reference": "26fb006a2c7b6cdd23d52157b05f8414ffa417b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6f9c2ba72f4295d7ce6cf9f79dbb18036291d335", - "reference": "6f9c2ba72f4295d7ce6cf9f79dbb18036291d335", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/26fb006a2c7b6cdd23d52157b05f8414ffa417b6", + "reference": "26fb006a2c7b6cdd23d52157b05f8414ffa417b6", "shasum": "" }, "require": { @@ -9278,20 +9476,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2020-02-14T07:43:07+00:00" + "time": "2020-03-30T14:14:32+00:00" }, { "name": "symfony/mime", - "version": "v5.0.5", + "version": "v5.0.7", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "9b3e5b5e58c56bbd76628c952d2b78556d305f3c" + "reference": "481b7d6da88922fb1e0d86a943987722b08f3955" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/9b3e5b5e58c56bbd76628c952d2b78556d305f3c", - "reference": "9b3e5b5e58c56bbd76628c952d2b78556d305f3c", + "url": "https://api.github.com/repos/symfony/mime/zipball/481b7d6da88922fb1e0d86a943987722b08f3955", + "reference": "481b7d6da88922fb1e0d86a943987722b08f3955", "shasum": "" }, "require": { @@ -9340,20 +9538,20 @@ "mime", "mime-type" ], - "time": "2020-02-04T09:41:09+00:00" + "time": "2020-03-27T16:56:45+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "9a02d6662660fe7bfadad63b5f0b0718d4c8b6b0" + "reference": "9072131b5e6e21203db3249c7db26b52897bc73e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/9a02d6662660fe7bfadad63b5f0b0718d4c8b6b0", - "reference": "9a02d6662660fe7bfadad63b5f0b0718d4c8b6b0", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/9072131b5e6e21203db3249c7db26b52897bc73e", + "reference": "9072131b5e6e21203db3249c7db26b52897bc73e", "shasum": "" }, "require": { @@ -9394,69 +9592,21 @@ "configuration", "options" ], - "time": "2020-01-04T13:00:46+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", - "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" + "url": "https://github.com/fabpot", + "type": "github" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "time": "2020-03-09T19:04:49+00:00" + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/polyfill-php70", @@ -9517,73 +9667,18 @@ ], "time": "2020-02-27T09:26:54+00:00" }, - { - "name": "symfony/polyfill-php72", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "37b0976c78b94856543260ce09b460a7bc852747" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747", - "reference": "37b0976c78b94856543260ce09b460a7bc852747", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2020-02-27T09:26:54+00:00" - }, { "name": "symfony/stopwatch", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "abc08d7c48987829bac301347faa10f7e8bbf4fb" + "reference": "e0324d3560e4128270e3f08617480d9233d81cfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/abc08d7c48987829bac301347faa10f7e8bbf4fb", - "reference": "abc08d7c48987829bac301347faa10f7e8bbf4fb", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e0324d3560e4128270e3f08617480d9233d81cfc", + "reference": "e0324d3560e4128270e3f08617480d9233d81cfc", "shasum": "" }, "require": { @@ -9620,20 +9715,34 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2020-01-04T13:00:46+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-27T16:54:36+00:00" }, { "name": "symfony/yaml", - "version": "v4.4.5", + "version": "v4.4.7", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "94d005c176db2080e98825d98e01e8b311a97a88" + "reference": "ef166890d821518106da3560086bfcbeb4fadfec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/94d005c176db2080e98825d98e01e8b311a97a88", - "reference": "94d005c176db2080e98825d98e01e8b311a97a88", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ef166890d821518106da3560086bfcbeb4fadfec", + "reference": "ef166890d821518106da3560086bfcbeb4fadfec", "shasum": "" }, "require": { @@ -9679,7 +9788,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2020-02-03T10:46:43+00:00" + "time": "2020-03-30T11:41:10+00:00" }, { "name": "theseer/fdomdocument", @@ -9763,16 +9872,16 @@ }, { "name": "vlucas/phpdotenv", - "version": "v2.6.1", + "version": "v2.6.3", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "2a7dcf7e3e02dc5e701004e51a6f304b713107d5" + "reference": "df4c4d08a639be4ef5d6d1322868f9e477553679" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2a7dcf7e3e02dc5e701004e51a6f304b713107d5", - "reference": "2a7dcf7e3e02dc5e701004e51a6f304b713107d5", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/df4c4d08a639be4ef5d6d1322868f9e477553679", + "reference": "df4c4d08a639be4ef5d6d1322868f9e477553679", "shasum": "" }, "require": { @@ -9780,8 +9889,14 @@ "symfony/polyfill-ctype": "^1.9" }, "require-dev": { + "ext-filter": "*", + "ext-pcre": "*", "phpunit/phpunit": "^4.8.35 || ^5.0" }, + "suggest": { + "ext-filter": "Required to use the boolean validator.", + "ext-pcre": "Required to use most of the library." + }, "type": "library", "extra": { "branch-alias": { @@ -9810,20 +9925,20 @@ "env", "environment" ], - "time": "2019-01-29T11:11:52+00:00" + "time": "2020-04-12T15:11:38+00:00" }, { "name": "webmozart/assert", - "version": "1.7.0", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "aed98a490f9a8f78468232db345ab9cf606cf598" + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598", - "reference": "aed98a490f9a8f78468232db345ab9cf606cf598", + "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6", "shasum": "" }, "require": { @@ -9831,7 +9946,7 @@ "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "vimeo/psalm": "<3.6.0" + "vimeo/psalm": "<3.9.1" }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" @@ -9858,7 +9973,7 @@ "check", "validate" ], - "time": "2020-02-14T12:15:55+00:00" + "time": "2020-04-18T12:12:48+00:00" }, { "name": "weew/helpers-array", @@ -9926,5 +10041,6 @@ "ext-zip": "*", "lib-libxml": "*" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/dev/tests/acceptance/tests/functional/Magento/ConfigurableProductWishlist/ActionGroup/_Deprecated_ActionGroup/StorefrontCustomerCheckConfigurableProductInWishlistActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/ConfigurableProductWishlist/ActionGroup/_Deprecated_ActionGroup/StorefrontCustomerCheckConfigurableProductInWishlistActionGroup.xml deleted file mode 100644 index d6d6819b20bfa..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/ConfigurableProductWishlist/ActionGroup/_Deprecated_ActionGroup/StorefrontCustomerCheckConfigurableProductInWishlistActionGroup.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="StorefrontCustomerCheckConfigurableProductInWishlist"> - <annotations> - <description>Validates that the provided Configurable Product and Product Option is present in the Storefront Wish List.</description> - </annotations> - <arguments> - <argument name="productVar"/> - <argument name="optionProductVar"/> - </arguments> - - <waitForElement selector="{{StorefrontCustomerWishlistProductSection.ProductTitleByName(productVar.name)}}" time="30" stepKey="assertWishlistProductName"/> - <see userInput="${{optionProductVar.price}}.00" selector="{{StorefrontCustomerWishlistProductSection.ProductPriceByName(productVar.name)}}" stepKey="AssertWishlistProductPrice"/> - <moveMouseOver selector="{{StorefrontCustomerWishlistProductSection.ProductInfoByName(productVar.name)}}" stepKey="wishlistMoveMouseOverProduct"/> - <seeElement selector="{{StorefrontCustomerWishlistProductSection.ProductAddToCartByName(productVar.name)}}" stepKey="AssertWishlistAddToCart"/> - <seeElement selector="{{StorefrontCustomerWishlistProductSection.ProductImageByName(productVar.name)}}" stepKey="AssertWishlistProductImage"/> - </actionGroup> -</actionGroups> diff --git a/dev/tests/acceptance/tests/functional/Magento/ConfigurableProductWishlist/ActionGroup/_Deprecated_ActionGroup/StorefrontCustomerCheckConfigurableProductInWishlistSidebarActionGroup.xml b/dev/tests/acceptance/tests/functional/Magento/ConfigurableProductWishlist/ActionGroup/_Deprecated_ActionGroup/StorefrontCustomerCheckConfigurableProductInWishlistSidebarActionGroup.xml deleted file mode 100644 index 4b22145f5130b..0000000000000 --- a/dev/tests/acceptance/tests/functional/Magento/ConfigurableProductWishlist/ActionGroup/_Deprecated_ActionGroup/StorefrontCustomerCheckConfigurableProductInWishlistSidebarActionGroup.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="StorefrontCustomerCheckConfigurableProductInWishlistSidebar"> - <annotations> - <description>Validates that the provided Configurable Product and Product Option is present in the Storefront Wish List sidebar.</description> - </annotations> - <arguments> - <argument name="productVar"/> - <argument name="optionProductVar"/> - </arguments> - - <waitForElement selector="{{StorefrontCustomerWishlistSidebarSection.ProductTitleByName(productVar.name)}}" time="30" stepKey="assertWishlistSidebarProductName"/> - <see userInput="${{optionProductVar.price}}.00" selector="{{StorefrontCustomerWishlistSidebarSection.ProductPriceByName(productVar.name)}}" stepKey="AssertWishlistSidebarProductPrice"/> - <seeElement selector="{{StorefrontCustomerWishlistSidebarSection.ProductAddToCartByName(productVar.name)}}" stepKey="AssertWishlistSidebarAddToCart"/> - <seeElement selector="{{StorefrontCustomerWishlistSidebarSection.ProductImageByName(productVar.name)}}" stepKey="AssertWishlistSidebarProductImage"/> - </actionGroup> -</actionGroups> diff --git a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/Gateway/Http/MockClient.php b/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/Gateway/Http/MockClient.php deleted file mode 100644 index 3c82d4eba740f..0000000000000 --- a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/Gateway/Http/MockClient.php +++ /dev/null @@ -1,135 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\TestModuleAuthorizenetAcceptjs\Gateway\Http; - -use Magento\Framework\Math\Random; -use Magento\Framework\Stdlib\ArrayManager; -use Magento\Payment\Gateway\Http\ClientInterface; -use Magento\Payment\Gateway\Http\TransferInterface; - -/** - * A client for mocking communicate with the Authorize.net API - */ -class MockClient implements ClientInterface -{ - /** - * @var Random - */ - private $random; - - /** - * @var ArrayManager - */ - private $arrayManager; - - /** - * @param Random $random - * @param ArrayManager $arrayManager - */ - public function __construct( - Random $random, - ArrayManager $arrayManager - ) { - $this->random = $random; - $this->arrayManager = $arrayManager; - } - - /** - * Places request to gateway. Returns result as ENV array - * - * @param TransferInterface $transferObject - * @return array - */ - public function placeRequest(TransferInterface $transferObject): array - { - $request = $transferObject->getBody(); - $nonce = $this->arrayManager->get('transactionRequest/payment/opaqueData/dataValue', $request); - $descriptor = $this->arrayManager->get('transactionRequest/payment/opaqueData/dataDescriptor', $request); - - $approve = true; - if ($nonce !== 'fake-nonce' || $descriptor !== 'COMMON.ACCEPT.INAPP.PAYMENT') { - $approve = false; - } - - return $this->createResponse($approve); - } - - /** - * Create mock response body - * - * @param bool $approve - * @return array - * @throws \Magento\Framework\Exception\LocalizedException - */ - private function createResponse(bool $approve): array - { - return [ - 'transactionResponse' => [ - 'responseCode' => $approve ? '1' : '2', - 'authCode' => strtoupper($this->random->getRandomString(6)), - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '2', - 'transId' => random_int(10000000000, 99999999999), - 'refTransId' => '', - 'transHash' => '', - 'testRequest' => '0', - 'accountNumber' => 'XXXX1111', - 'accountType' => 'Visa', - 'messages' => $approve ? $this->getApprovalMessage() : $this->getDeclineMessage(), - 'userFields' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction', - ], - ], - 'transHashSha2' => 'fake-hash', - 'SupplementalDataQualificationIndicator' => '0', - ], - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'I00001', - 'text' => 'Successful.', - ], - ], - ], - ]; - } - - /** - * Provide approval message for response - * - * @return array - */ - private function getApprovalMessage(): array - { - return [ - [ - 'code' => '1', - 'description' => 'This transaction has been approved.', - ], - ]; - } - - /** - * Provide decline message for response - * - * @return array - */ - private function getDeclineMessage(): array - { - return [ - [ - 'code' => '2', - 'description' => 'This transaction has been declined.', - ], - ]; - } -} diff --git a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/Gateway/Validator/TransactionHashValidator.php b/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/Gateway/Validator/TransactionHashValidator.php deleted file mode 100644 index b0e281e9faa5c..0000000000000 --- a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/Gateway/Validator/TransactionHashValidator.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\TestModuleAuthorizenetAcceptjs\Gateway\Validator; - -use Magento\Payment\Gateway\Validator\AbstractValidator; -use Magento\Payment\Gateway\Validator\ResultInterface; - -/** - * Force validation of the transaction hash - */ -class TransactionHashValidator extends AbstractValidator -{ - /** - * Skip validation of transaction hash in mock response - * - * @param array $validationSubject - * @return ResultInterface - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function validate(array $validationSubject): ResultInterface - { - return $this->createResult(true); - } -} diff --git a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/etc/di.xml deleted file mode 100644 index 9f19743cfc205..0000000000000 --- a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/etc/di.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <preference for="Magento\AuthorizenetAcceptjs\Gateway\Http\Client" type="Magento\TestModuleAuthorizenetAcceptjs\Gateway\Http\MockClient" /> - <preference for="Magento\AuthorizenetAcceptjs\Gateway\Validator\TransactionHashValidator" type="Magento\TestModuleAuthorizenetAcceptjs\Gateway\Validator\TransactionHashValidator" /> -</config> diff --git a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/registration.php b/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/registration.php deleted file mode 100644 index 28c5861ed5fb8..0000000000000 --- a/dev/tests/api-functional/_files/Magento/TestModuleAuthorizenetAcceptjs/registration.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Framework\Component\ComponentRegistrar; - -$registrar = new ComponentRegistrar(); -if ($registrar->getPath(ComponentRegistrar::MODULE, 'Magento_TestModuleAuthorizenetAcceptjs') === null) { - ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_TestModuleAuthorizenetAcceptjs', __DIR__); -} diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 8c3ec20b0ede5..2512de3537f28 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -280,7 +280,7 @@ public function testCreateWithMultipleWebsites() $websitesData = [ 'website_ids' => [ 1, - (int) $website->getId(), + (int)$website->getId(), ] ]; $productBuilder[ProductInterface::EXTENSION_ATTRIBUTES_KEY] = $websitesData; @@ -381,97 +381,6 @@ public function testCreate($product) $this->deleteProduct($product[ProductInterface::SKU]); } - /** - * Media gallery entries with external videos - * - * @return array - */ - public function externalVideoDataProvider(): array - { - return [ - [ - [ - [ - 'media_type' => 'external-video', - 'disabled' => false, - 'label' => 'Test Video Created', - 'types' => [], - 'position' => 1, - 'content' => [ - 'type' => 'image/png', - 'name' => 'thumbnail.png', - 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' - . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', - ], - 'extension_attributes' => [ - 'video_content' => [ - 'media_type' => 'external-video', - 'video_provider' => 'youtube', - 'video_url' => 'https://www.youtube.com/', - 'video_title' => 'Video title', - 'video_description' => 'Video description', - 'video_metadata' => 'Video meta', - ], - ], - ] - ] - ], - [ - [ - [ - 'media_type' => 'external-video', - 'disabled' => false, - 'label' => 'Test Video Updated', - 'types' => [], - 'position' => 1, - 'content' => [ - 'type' => 'image/png', - 'name' => 'thumbnail.png', - 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' - . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', - ], - 'extension_attributes' => [ - 'video_content' => [ - 'media_type' => 'external-video', - 'video_provider' => 'vimeo', - 'video_url' => 'https://www.vimeo.com/', - 'video_title' => 'Video title', - 'video_description' => 'Video description', - 'video_metadata' => 'Video meta', - ], - ], - ] - ] - ] - ]; - } - - /** - * Test create/ update product with external video media gallery entry - * - * @dataProvider externalVideoDataProvider - * @param array $mediaGalleryData - */ - public function testCreateWithExternalVideo(array $mediaGalleryData) - { - $simpleProductBaseData = $this->getSimpleProductData( - [ - ProductInterface::NAME => 'Product With Ext. Video', - ProductInterface::SKU => 'prod-with-ext-video' - ] - ); - - $simpleProductBaseData['media_gallery_entries'] = $mediaGalleryData; - - $response = $this->saveProduct($simpleProductBaseData); - $this->assertEquals( - $simpleProductBaseData['media_gallery_entries'][0]['extension_attributes'], - $response["media_gallery_entries"][0]["extension_attributes"] - ); - } - /** * @param array $fixtureProduct * @@ -1186,6 +1095,86 @@ public function testGetListWithFilteringByStoreDataProvider() ]; } + /** + * Test getList() method with pagination + * + * @param int $pageSize + * @param int $currentPage + * @param int $expectedCount + * + * @magentoAppIsolation enabled + * @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php + * @dataProvider productPaginationDataProvider + */ + public function testGetListPagination(int $pageSize, int $currentPage, int $expectedCount) + { + $fixtureProducts = 5; + + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $categoryFilter = $filterBuilder->setField('category_id') + ->setValue(333) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$categoryFilter]); + $searchCriteriaBuilder->setPageSize($pageSize); + $searchCriteriaBuilder->setCurrentPage($currentPage); + + $searchData = $searchCriteriaBuilder->create()->__toArray(); + $requestData = ['searchCriteria' => $searchData]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + + $searchResult = $this->_webApiCall($serviceInfo, $requestData); + + $this->assertEquals($fixtureProducts, $searchResult['total_count']); + $this->assertCount($expectedCount, $searchResult['items']); + } + + /** + * Keep in mind: Fixture contains 5 products + * + * @return array + */ + public function productPaginationDataProvider() + { + return [ + 'expect-all-items' => [ + 'pageSize' => 10, + 'currentPage' => 1, + 'expectedCount' => 5 + ], + 'expect-page=size-items' => [ + 'pageSize' => 2, + 'currentPage' => 1, + 'expectedCount' => 2 + ], + 'expect-less-than-pagesize-elements' => [ + 'pageSize' => 3, + 'currentPage' => 2, + 'expectedCount' => 2 + ], + 'expect-no-items' => [ + 'pageSize' => 100, + 'currentPage' => 99, + 'expectedCount' => 0 + ] + ]; + } + /** * Test getList() method with multiple filter groups and sorting and pagination * @@ -1223,7 +1212,7 @@ public function testGetListWithMultipleFilterGroupsAndSortingAndPagination() $sortOrder = $sortOrderBuilder->setField('meta_title')->setDirection(SortOrder::SORT_DESC)->create(); /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ - $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); $searchCriteriaBuilder->addFilters([$filter5]); @@ -1815,8 +1804,8 @@ private function assertMultiselectValue($productSku, $multiselectAttributeCode, * Test design settings authorization * * @magentoApiDataFixture Magento/User/_files/user_with_custom_role.php - * @throws \Throwable * @return void + * @throws \Throwable */ public function testSaveDesign(): void { diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ProductRepositoryTest.php index 1dc7ca1ad44a6..c8ecab9ce54d8 100644 --- a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ProductRepositoryTest.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\ConfigurableProduct\Api; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Entity\Attribute; +use Magento\Eav\Model\Config; +use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection; use Magento\Framework\Api\ExtensibleDataInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Webapi\Rest\Request; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -22,31 +26,31 @@ class ProductRepositoryTest extends WebapiAbstract const CONFIGURABLE_PRODUCT_SKU = 'configurable-product-sku'; /** - * @var \Magento\Eav\Model\Config + * @var Config */ protected $eavConfig; /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManagerInterface */ protected $objectManager; /** - * @var \Magento\Catalog\Model\Entity\Attribute + * @var Attribute */ protected $configurableAttribute; /** - * Execute per test initialization + * @inheritdoc */ public function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $this->eavConfig = $this->objectManager->get(\Magento\Eav\Model\Config::class); + $this->eavConfig = $this->objectManager->get(Config::class); } /** - * Execute per test cleanup + * @inheritdoc */ public function tearDown() { @@ -54,16 +58,26 @@ public function tearDown() parent::tearDown(); } + /** + * Retrieve configurable attribute options + * + * @return array + */ protected function getConfigurableAttributeOptions() { - /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection $optionCollection */ + /** @var Collection $optionCollection */ $optionCollection = $this->objectManager->create( - \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection::class + Collection::class ); $options = $optionCollection->setAttributeFilter($this->configurableAttribute->getId())->getData(); return $options; } + /** + * Create configurable product by web api + * + * @return array + */ protected function createConfigurableProduct() { $productId1 = 10; @@ -254,7 +268,6 @@ public function testUpdateConfigurableProductLinks() $this->assertEquals([$productId1], $resultConfigurableProductLinks); //adding back the product links, the option value should be restored - unset($response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_options']); $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['configurable_product_links'] = [$productId1, $productId2]; //set the value for required attribute @@ -286,7 +299,7 @@ public function testUpdateConfigurableProductLinksWithNonExistingProduct() $productId1, $nonExistingId ]; - $expectedMessage = 'The product was unable to be saved. Please try again.'; + $expectedMessage = 'The product that was requested doesn\'t exist. Verify the product and try again.'; try { $this->saveProduct($response); $this->fail("Expected exception"); @@ -362,7 +375,7 @@ public function testUpdateConfigurableProductLinksWithWithoutVariationAttributes $productId1, $productId2 ]; - $expectedMessage = 'The product was unable to be saved. Please try again.'; + $expectedMessage = 'The product that was requested doesn\'t exist. Verify the product and try again.'; try { $this->saveProduct($response); $this->fail("Expected exception"); @@ -389,7 +402,7 @@ protected function getProduct($productSku) $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH . '/' . $productSku, - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + 'httpMethod' => Request::HTTP_METHOD_GET, ], 'soap' => [ 'service' => self::SERVICE_NAME, @@ -415,7 +428,7 @@ protected function createProduct($product) $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH, - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST + 'httpMethod' => Request::HTTP_METHOD_POST ], 'soap' => [ 'service' => self::SERVICE_NAME, @@ -440,7 +453,7 @@ protected function deleteProductBySku($productSku) $serviceInfo = [ 'rest' => [ 'resourcePath' => $resourcePath, - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE + 'httpMethod' => Request::HTTP_METHOD_DELETE ], 'soap' => [ 'service' => self::SERVICE_NAME, @@ -475,7 +488,7 @@ protected function saveProduct($product) $serviceInfo = [ 'rest' => [ 'resourcePath' => $resourcePath, - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT + 'httpMethod' => Request::HTTP_METHOD_PUT ], 'soap' => [ 'service' => self::SERVICE_NAME, diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php deleted file mode 100644 index d6954c249f209..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php +++ /dev/null @@ -1,291 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\GraphQl\AuthorizenetAcceptjs\Customer; - -use Magento\Framework\Registry; -use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; -use Magento\Integration\Api\CustomerTokenServiceInterface; -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\ResourceModel\Order\CollectionFactory; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\TestCase\GraphQlAbstract; - -/** - * Test setting payment method and placing order with AuthorizenetAcceptjs - */ -class SetPaymentMethodTest extends GraphQlAbstract -{ - private const VALID_DESCRIPTOR = 'COMMON.ACCEPT.INAPP.PAYMENT'; - private const VALID_NONCE = 'fake-nonce'; - - /** - * @var CustomerTokenServiceInterface - */ - private $customerTokenService; - - /** - * @var GetMaskedQuoteIdByReservedOrderId - */ - private $getMaskedQuoteIdByReservedOrderId; - - /** - * @var CollectionFactory - */ - private $orderCollectionFactory; - - /** - * @var OrderRepositoryInterface - */ - private $orderRepository; - - /** - * @var Registry - */ - private $registry; - - /** - * @inheritdoc - */ - protected function setUp() - { - $objectManager = Bootstrap::getObjectManager(); - $this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); - $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); - $this->orderCollectionFactory = $objectManager->get(CollectionFactory::class); - $this->orderRepository = $objectManager->get(OrderRepositoryInterface::class); - $this->registry = Bootstrap::getObjectManager()->get(Registry::class); - } - - /** - * @magentoApiDataFixture Magento/Customer/_files/customer.php - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php - * @magentoApiDataFixture Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs.php - * @magentoConfigFixture default_store carriers/flatrate/active 1 - * @magentoConfigFixture default_store carriers/tablerate/active 1 - * @magentoConfigFixture default_store carriers/freeshipping/active 1 - * @param string $nonce - * @param string $descriptor - * @param bool $expectSuccess - * @dataProvider dataProviderTestPlaceOrder - */ - public function testPlaceOrder(string $nonce, string $descriptor, bool $expectSuccess) - { - $reservedOrderId = 'test_quote'; - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute($reservedOrderId); - - $setPaymentMutation = $this->getSetPaymentMutation($maskedQuoteId, $descriptor, $nonce); - $setPaymentResponse = $this->graphQlMutation($setPaymentMutation, [], '', $this->getHeaderMap()); - - $this->assertSetPaymentMethodResponse($setPaymentResponse, 'authorizenet_acceptjs'); - - $placeOrderQuery = $this->getPlaceOrderMutation($maskedQuoteId); - - if (!$expectSuccess) { - $this->expectException(\Exception::class); - $this->expectExceptionMessage('Transaction has been declined. Please try again later.'); - } - - $placeOrderResponse = $this->graphQlMutation($placeOrderQuery, [], '', $this->getHeaderMap()); - - $this->assertPlaceOrderResponse($placeOrderResponse, $reservedOrderId); - } - - public function dataProviderTestPlaceOrder(): array - { - return [ - [static::VALID_NONCE, static::VALID_DESCRIPTOR, true], - ['nonce', static::VALID_DESCRIPTOR, false], - [static::VALID_NONCE, 'descriptor', false], - ]; - } - - /** - * @magentoConfigFixture default_store carriers/flatrate/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login def_login - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key def_trans_key - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/public_client_key def_public_client_key - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key def_trans_signature_key - * @magentoApiDataFixture Magento/Customer/_files/customer.php - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php - * @dataProvider dataProviderSetPaymentInvalidInput - * @param \Closure $getMutationClosure - * @param array $expectedMessages - * @expectedException \Exception - */ - public function testSetPaymentInvalidInput(\Closure $getMutationClosure, array $expectedMessages) - { - $reservedOrderId = 'test_quote'; - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute($reservedOrderId); - - $setPaymentMutation = $getMutationClosure($maskedQuoteId); - - foreach ($expectedMessages as $expectedMessage) { - $this->expectExceptionMessage($expectedMessage); - } - $this->graphQlMutation($setPaymentMutation, [], '', $this->getHeaderMap()); - } - - /** - * Data provider for testSetPaymentInvalidInput - * - * @return array - */ - public function dataProviderSetPaymentInvalidInput(): array - { - return [ - [ - function (string $maskedQuoteId) { - return $this->getInvalidSetPaymentMutation($maskedQuoteId); - }, - [ - 'Required parameter "authorizenet_acceptjs" for "payment_method" is missing.' - ] - ] - ]; - } - - /** - * Get setPaymentMethodOnCart missing additional data property - * - * @param string $maskedQuoteId - * @return string - */ - private function getInvalidSetPaymentMutation(string $maskedQuoteId): string - { - return <<<QUERY -mutation { - setPaymentMethodOnCart(input:{ - cart_id:"{$maskedQuoteId}" - payment_method:{ - code:"authorizenet_acceptjs" - } - }) { - cart { - selected_payment_method { - code - } - } - } -} -QUERY; - } - - private function assertPlaceOrderResponse(array $response, string $reservedOrderId): void - { - self::assertArrayHasKey('placeOrder', $response); - self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_number', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); - } - - private function assertSetPaymentMethodResponse(array $response, string $methodCode): void - { - self::assertArrayHasKey('setPaymentMethodOnCart', $response); - self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); - self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); - self::assertArrayHasKey('code', $response['setPaymentMethodOnCart']['cart']['selected_payment_method']); - self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); - } - - /** - * Create setPaymentMethodOnCart mutation - * - * @param string $maskedQuoteId - * @param string $descriptor - * @param string $nonce - * @return string - */ - private function getSetPaymentMutation(string $maskedQuoteId, string $descriptor, string $nonce): string - { - return <<<QUERY -mutation { - setPaymentMethodOnCart(input:{ - cart_id:"{$maskedQuoteId}" - payment_method:{ - code:"authorizenet_acceptjs" - authorizenet_acceptjs:{ - opaque_data_descriptor: "{$descriptor}" - opaque_data_value: "{$nonce}" - cc_last_4: 1111 - } - } - }) { - cart { - selected_payment_method { - code - } - } - } -} -QUERY; - } - - /** - * Create placeOrder mutation - * - * @param string $maskedQuoteId - * @return string - */ - private function getPlaceOrderMutation(string $maskedQuoteId): string - { - return <<<QUERY -mutation { - placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { - order { - order_number - } - } -} -QUERY; - } - - /** - * Get authorization headers for requests - * - * @param string $username - * @param string $password - * @return array - * @throws \Magento\Framework\Exception\AuthenticationException - */ - private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array - { - $customerToken = $this->customerTokenService->createCustomerAccessToken($username, $password); - $headerMap = ['Authorization' => 'Bearer ' . $customerToken]; - return $headerMap; - } - - /** - * @inheritdoc - */ - public function tearDown() - { - $this->registry->unregister('isSecureArea'); - $this->registry->register('isSecureArea', true); - - $orderCollection = $this->orderCollectionFactory->create(); - foreach ($orderCollection as $order) { - $this->orderRepository->delete($order); - } - $this->registry->unregister('isSecureArea'); - $this->registry->register('isSecureArea', false); - - parent::tearDown(); - } -} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php deleted file mode 100644 index 322d984f5fa75..0000000000000 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php +++ /dev/null @@ -1,198 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\GraphQl\AuthorizenetAcceptjs\Guest; - -use Magento\Framework\Registry; -use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; -use Magento\Integration\Api\CustomerTokenServiceInterface; -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\ResourceModel\Order\CollectionFactory; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\TestCase\GraphQlAbstract; - -/** - * Test setting payment method and placing order with AuthorizenetAcceptjs - */ -class SetPaymentMethodTest extends GraphQlAbstract -{ - private const VALID_DESCRIPTOR = 'COMMON.ACCEPT.INAPP.PAYMENT'; - private const VALID_NONCE = 'fake-nonce'; - - /** - * @var CustomerTokenServiceInterface - */ - private $customerTokenService; - - /** - * @var GetMaskedQuoteIdByReservedOrderId - */ - private $getMaskedQuoteIdByReservedOrderId; - - /** - * @var CollectionFactory - */ - private $orderCollectionFactory; - - /** - * @var OrderRepositoryInterface - */ - private $orderRepository; - - /** - * @var Registry - */ - private $registry; - - /** - * @inheritdoc - */ - protected function setUp() - { - $objectManager = Bootstrap::getObjectManager(); - $this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); - $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); - $this->orderCollectionFactory = $objectManager->get(CollectionFactory::class); - $this->orderRepository = $objectManager->get(OrderRepositoryInterface::class); - $this->registry = Bootstrap::getObjectManager()->get(Registry::class); - } - - /** - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/set_guest_email.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php - * @magentoApiDataFixture Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs.php - * @magentoConfigFixture default_store carriers/flatrate/active 1 - * @magentoConfigFixture default_store carriers/tablerate/active 1 - * @magentoConfigFixture default_store carriers/freeshipping/active 1 - * @param string $nonce - * @param string $descriptor - * @param bool $expectSuccess - * @dataProvider dataProviderTestPlaceOrder - */ - public function testPlaceOrder(string $nonce, string $descriptor, bool $expectSuccess) - { - $reservedOrderId = 'test_quote'; - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute($reservedOrderId); - - $setPaymentMutation = $this->getSetPaymentMutation($maskedQuoteId, $descriptor, $nonce); - $setPaymentResponse = $this->graphQlMutation($setPaymentMutation); - - $this->assertSetPaymentMethodResponse($setPaymentResponse, 'authorizenet_acceptjs'); - - $placeOrderQuery = $this->getPlaceOrderMutation($maskedQuoteId); - - if (!$expectSuccess) { - $this->expectException(\Exception::class); - $this->expectExceptionMessage('Transaction has been declined. Please try again later.'); - } - - $placeOrderResponse = $this->graphQlMutation($placeOrderQuery); - - $this->assertPlaceOrderResponse($placeOrderResponse, $reservedOrderId); - } - - public function dataProviderTestPlaceOrder(): array - { - return [ - [static::VALID_NONCE, static::VALID_DESCRIPTOR, true], - ['nonce', static::VALID_DESCRIPTOR, false], - [static::VALID_NONCE, 'descriptor', false], - ]; - } - - private function assertPlaceOrderResponse(array $response, string $reservedOrderId): void - { - self::assertArrayHasKey('placeOrder', $response); - self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_number', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); - } - - private function assertSetPaymentMethodResponse(array $response, string $methodCode): void - { - self::assertArrayHasKey('setPaymentMethodOnCart', $response); - self::assertArrayHasKey('cart', $response['setPaymentMethodOnCart']); - self::assertArrayHasKey('selected_payment_method', $response['setPaymentMethodOnCart']['cart']); - self::assertArrayHasKey('code', $response['setPaymentMethodOnCart']['cart']['selected_payment_method']); - self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); - } - - /** - * Create setPaymentMethodOnCart mutation - * - * @param string $maskedQuoteId - * @param string $descriptor - * @param string $nonce - * @return string - */ - private function getSetPaymentMutation(string $maskedQuoteId, string $descriptor, string $nonce): string - { - return <<<QUERY -mutation { - setPaymentMethodOnCart(input:{ - cart_id:"{$maskedQuoteId}" - payment_method:{ - code:"authorizenet_acceptjs" - authorizenet_acceptjs:{ - opaque_data_descriptor: "{$descriptor}" - opaque_data_value: "{$nonce}" - cc_last_4: 1111 - } - } - }) { - cart { - selected_payment_method { - code - } - } - } -} -QUERY; - } - - /** - * Create placeOrder mutation - * - * @param string $maskedQuoteId - * @return string - */ - private function getPlaceOrderMutation(string $maskedQuoteId): string - { - return <<<QUERY -mutation { - placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { - order { - order_number - } - } -} -QUERY; - } - - /** - * @inheritdoc - */ - public function tearDown() - { - $this->registry->unregister('isSecureArea'); - $this->registry->register('isSecureArea', true); - - $orderCollection = $this->orderCollectionFactory->create(); - foreach ($orderCollection as $order) { - $this->orderRepository->delete($order); - } - $this->registry->unregister('isSecureArea'); - $this->registry->register('isSecureArea', false); - - parent::tearDown(); - } -} diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php index 86d36c1c767f7..615438d52e764 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php @@ -38,6 +38,33 @@ public function testProductSmallImageUrlWithExistingImage() self::assertTrue($this->checkImageExists($response['products']['items'][0]['small_image']['url'])); } + /** + * Test for get product image placeholder + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testProductSmallImageUrlPlaceholder() + { + $productSku = 'simple'; + $query = <<<QUERY +{ + products(filter: {sku: {eq: "{$productSku}"}}) { + items { + small_image { + url + } + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + $responseImage = $response['products']['items'][0]['small_image']; + + self::assertArrayHasKey('url', $responseImage); + self::assertContains('placeholder/small_image.jpg', $responseImage['url']); + self::assertTrue($this->checkImageExists($responseImage['url'])); + } + /** * @magentoApiDataFixture Magento/Catalog/_files/product_with_multiple_images.php */ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php index 74a311932991e..cd96e3af6f012 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSelectedPaymentMethodTest.php @@ -34,7 +34,6 @@ class GetSelectedPaymentMethodTest extends GraphQlAbstract * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -60,7 +59,6 @@ public function testGetSelectedPaymentMethod() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -103,7 +101,6 @@ public function testGetSelectedPaymentMethodFromNonExistentCart() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_checkmo_payment_method.php @@ -152,7 +149,7 @@ private function getQuery(string $maskedQuoteId): string { return <<<QUERY { - cart(cart_id:"$maskedQuoteId") { + cart(cart_id:"$maskedQuoteId") { selected_payment_method { code } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php index 88c57cf2fb282..11dc10beb72e2 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php @@ -69,7 +69,6 @@ protected function setUp() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -236,7 +235,6 @@ public function testPlaceOrderWithOutOfStockProduct() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -265,7 +263,6 @@ public function testPlaceOrderOfGuestCart() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodsOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodsOnCartTest.php index 138d27ef26483..dbd6bb90f9a03 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodsOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetOfflinePaymentMethodsOnCartTest.php @@ -51,7 +51,6 @@ protected function setUp() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * * @param string $methodCode * @param string $methodTitle @@ -98,7 +97,6 @@ public function offlinePaymentMethodDataProvider(): array * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 */ public function testSetPurchaseOrderPaymentMethod() { @@ -110,7 +108,7 @@ public function testSetPurchaseOrderPaymentMethod() $query = <<<QUERY mutation { setPaymentMethodOnCart(input: { - cart_id: "{$maskedQuoteId}", + cart_id: "{$maskedQuoteId}", payment_method: { code: "{$methodCode}" purchase_order_number: "{$poNumber}" @@ -155,7 +153,7 @@ private function getQuery( return <<<QUERY mutation { setPaymentMethodOnCart(input: { - cart_id: "{$maskedQuoteId}", + cart_id: "{$maskedQuoteId}", payment_method: { code: "{$methodCode}" } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php index 74f8e3c2e37dd..fa3cbb5a9b457 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodOnCartTest.php @@ -251,7 +251,6 @@ public function dataProviderSetPaymentMethodWithoutRequiredParameters(): array * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -288,7 +287,7 @@ private function getQuery( payment_method: { code: "$methodCode" } - }) { + }) { cart { selected_payment_method { code diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPurchaseOrderPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPurchaseOrderPaymentMethodOnCartTest.php index 6b9e46fd153eb..1e64679b4abd8 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPurchaseOrderPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPurchaseOrderPaymentMethodOnCartTest.php @@ -49,7 +49,6 @@ protected function setUp() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 */ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() { @@ -65,7 +64,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() code: "$methodCode" purchase_order_number: "$purchaseOrderNumber" } - }) { + }) { cart { selected_payment_method { code @@ -97,7 +96,6 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * * @expectedException Exception * @expectedExceptionMessage Purchase order number is a required field. @@ -114,7 +112,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithoutPurchaseOrderNumbe payment_method: { code: "$methodCode" } - }) { + }) { cart { selected_payment_method { code @@ -150,7 +148,7 @@ public function testSetDisabledPurchaseOrderPaymentMethodOnCart() code: "$methodCode" purchase_order_number: "$purchaseOrderNumber" } - }) { + }) { cart { selected_payment_method { code diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php index 60c3cc2e8b24e..f67638015988b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php @@ -17,7 +17,7 @@ use Magento\TestFramework\TestCase\GraphQlAbstract; /** - * Allow guest checkout option test + * Test for guest checkout. */ class AllowGuestCheckoutOptionTest extends GraphQlAbstract { @@ -169,7 +169,7 @@ public function testSetPaymentOnCartWithGuestCheckoutDisabled() $query = <<<QUERY mutation { setPaymentMethodOnCart(input: { - cart_id: "{$maskedQuoteId}", + cart_id: "{$maskedQuoteId}", payment_method: { code: "{$methodCode}" } @@ -254,9 +254,9 @@ public function testSetShippingMethodOnCartWithGuestCheckoutDisabled() $query = <<<QUERY mutation { - setShippingMethodsOnCart(input: + setShippingMethodsOnCart(input: { - cart_id: "$maskedQuoteId", + cart_id: "$maskedQuoteId", shipping_methods: [{ carrier_code: "$carrierCode" method_code: "$methodCode" @@ -284,7 +284,6 @@ public function testSetShippingMethodOnCartWithGuestCheckoutDisabled() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/set_guest_email.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php index 9536f078402a4..7619212942812 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSelectedPaymentMethodTest.php @@ -34,7 +34,6 @@ protected function setUp() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_checkmo_payment_method.php @@ -60,7 +59,6 @@ public function testGetSelectedPaymentMethod() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php */ @@ -100,7 +98,6 @@ public function testGetSelectedPaymentMethodFromNonExistentCart() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -126,7 +123,7 @@ private function getQuery(string $maskedQuoteId): string { return <<<QUERY { - cart(cart_id:"$maskedQuoteId") { + cart(cart_id:"$maskedQuoteId") { selected_payment_method { code } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php index bf31d3c6fa3f4..4879ff39b709e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php @@ -61,7 +61,6 @@ protected function setUp() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/set_guest_email.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php @@ -104,7 +103,6 @@ public function testPlaceOrderIfCartIdIsEmpty() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -257,7 +255,6 @@ public function testPlaceOrderWithOutOfStockProduct() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodsOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodsOnCartTest.php index 6c45227c47742..7a92ef8df201d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodsOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetOfflinePaymentMethodsOnCartTest.php @@ -43,7 +43,6 @@ protected function setUp() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * * @param string $methodCode * @param string $methodTitle @@ -89,7 +88,6 @@ public function offlinePaymentMethodDataProvider(): array * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 */ public function testSetPurchaseOrderPaymentMethod() { @@ -101,7 +99,7 @@ public function testSetPurchaseOrderPaymentMethod() $query = <<<QUERY mutation { setPaymentMethodOnCart(input: { - cart_id: "{$maskedQuoteId}", + cart_id: "{$maskedQuoteId}", payment_method: { code: "{$methodCode}" purchase_order_number: "{$poNumber}" @@ -147,7 +145,7 @@ private function getQuery( return <<<QUERY mutation { setPaymentMethodOnCart(input: { - cart_id: "{$maskedQuoteId}", + cart_id: "{$maskedQuoteId}", payment_method: { code: "{$methodCode}" } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php index e38ccf78d420b..e506c7c784f3f 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php @@ -155,7 +155,6 @@ public function testSetPaymentOnNonExistentCart() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -230,7 +229,7 @@ private function getQuery( payment_method: { code: "$methodCode" } - }) { + }) { order { order_number } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php index 08c7bdd8dbc52..7c02589261a4a 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodOnCartTest.php @@ -200,7 +200,6 @@ public function dataProviderSetPaymentMethodWithoutRequiredParameters(): array * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php @@ -250,7 +249,7 @@ private function getQuery( return <<<QUERY mutation { setPaymentMethodOnCart(input: { - cart_id: "{$maskedQuoteId}", + cart_id: "{$maskedQuoteId}", payment_method: { code: "{$methodCode}" } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPurchaseOrderPaymentMethodOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPurchaseOrderPaymentMethodOnCartTest.php index 8b6317bd76c36..067c65fe85b6c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPurchaseOrderPaymentMethodOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPurchaseOrderPaymentMethodOnCartTest.php @@ -41,7 +41,6 @@ protected function setUp() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 */ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() { @@ -57,7 +56,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() code: "$methodCode" purchase_order_number: "$purchaseOrderNumber" } - }) { + }) { cart { selected_payment_method { code @@ -88,7 +87,6 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithSimpleProduct() * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 * * @expectedException Exception * @expectedExceptionMessage Purchase order number is a required field. @@ -105,7 +103,7 @@ public function testSetPurchaseOrderPaymentMethodOnCartWithoutPurchaseOrderNumbe payment_method: { code: "$methodCode" } - }) { + }) { cart { selected_payment_method { code @@ -140,7 +138,7 @@ public function testSetDisabledPurchaseOrderPaymentMethodOnCart() code: "$methodCode" purchase_order_number: "$purchaseOrderNumber" } - }) { + }) { cart { selected_payment_method { code diff --git a/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php b/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php new file mode 100644 index 0000000000000..7c38cf15545c6 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/ProductVideo/ProductVideoExternalSourceTest.php @@ -0,0 +1,178 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ProductVideo; + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\TestFramework\TestCase\WebapiAbstract; + +/** + * Test for \Magento\ProductVideo feature + * + * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ProductVideoExternalSourceTest extends WebapiAbstract +{ + const SERVICE_NAME = 'catalogProductRepositoryV1'; + const SERVICE_VERSION = 'V1'; + const RESOURCE_PATH = '/V1/products'; + + /** + * Media gallery entries with external videos + * + * @return array + */ + public function externalVideoDataProvider(): array + { + return [ + 'youtube-external-video' => [ + [ + 'media_type' => 'external-video', + 'disabled' => false, + 'label' => 'Test Video Created', + 'types' => [], + 'position' => 1, + 'content' => $this->getVideoThumbnailStub(), + 'extension_attributes' => [ + 'video_content' => [ + 'media_type' => 'external-video', + 'video_provider' => 'youtube', + 'video_url' => 'https://www.youtube.com/', + 'video_title' => 'Video title', + 'video_description' => 'Video description', + 'video_metadata' => 'Video meta', + ], + ], + ] + ], + 'vimeo-external-video' => [ + [ + 'media_type' => 'external-video', + 'disabled' => false, + 'label' => 'Test Video Updated', + 'types' => [], + 'position' => 1, + 'content' => $this->getVideoThumbnailStub(), + 'extension_attributes' => [ + 'video_content' => [ + 'media_type' => 'external-video', + 'video_provider' => 'vimeo', + 'video_url' => 'https://www.vimeo.com/', + 'video_title' => 'Video title', + 'video_description' => 'Video description', + 'video_metadata' => 'Video meta', + ], + ], + ] + ] + ]; + } + + /** + * Returns the array of data for Video thumbnail + * + * @return array|string[] + */ + private function getVideoThumbnailStub(): array + { + return [ + 'type' => 'image/png', + 'name' => 'thumbnail.png', + 'base64_encoded_data' => 'iVBORw0KGgoAAAANSUhEUgAAAP8AAADGCAMAAAAqo6adAAAAA1BMVEUAAP79f' + . '+LBAAAASElEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + . 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA+BsYAAAF7hZJ0AAAAAElFTkSuQmCC', + ]; + } + + /** + * Test create/ update product with external video media gallery entry + * + * @dataProvider externalVideoDataProvider + * @param array $mediaGalleryData + */ + public function testCreateWithExternalVideo(array $mediaGalleryData) + { + $simpleProductBaseData = $this->getSimpleProductData( + [ + ProductInterface::NAME => 'Product With Ext. Video', + ProductInterface::SKU => 'prod-with-ext-video' + ] + ); + + $simpleProductBaseData['media_gallery_entries'] = [$mediaGalleryData]; + + $response = $this->saveProduct($simpleProductBaseData); + $this->assertEquals( + $simpleProductBaseData['media_gallery_entries'][0]['extension_attributes'], + $response["media_gallery_entries"][0]["extension_attributes"] + ); + } + + /** + * Get Simple Product Data + * + * @param array $productData + * @return array + */ + protected function getSimpleProductData($productData = []) + { + return [ + ProductInterface::SKU => isset($productData[ProductInterface::SKU]) + ? $productData[ProductInterface::SKU] : uniqid('sku-', true), + ProductInterface::NAME => isset($productData[ProductInterface::NAME]) + ? $productData[ProductInterface::NAME] : uniqid('sku-', true), + ProductInterface::VISIBILITY => 4, + ProductInterface::TYPE_ID => 'simple', + ProductInterface::PRICE => 3.62, + ProductInterface::STATUS => 1, + ProductInterface::ATTRIBUTE_SET_ID => 4, + 'custom_attributes' => [ + ['attribute_code' => 'cost', 'value' => ''], + ['attribute_code' => 'description', 'value' => 'Description'], + ] + ]; + } + + /** + * Save Product + * + * @param $product + * @param string|null $storeCode + * @param string|null $token + * @return mixed + */ + protected function saveProduct($product, $storeCode = null, ?string $token = null) + { + if (isset($product['custom_attributes'])) { + foreach ($product['custom_attributes'] as &$attribute) { + if ($attribute['attribute_code'] == 'category_ids' + && !is_array($attribute['value']) + ) { + $attribute['value'] = [""]; + } + } + } + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'Save', + ], + ]; + if ($token) { + $serviceInfo['rest']['token'] = $serviceInfo['soap']['token'] = $token; + } + $requestData = ['product' => $product]; + + return $this->_webApiCall($serviceInfo, $requestData, null, $storeCode); + } +} diff --git a/dev/tests/functional/credentials.xml.dist b/dev/tests/functional/credentials.xml.dist index 89ea0f23ef30e..97c854dcb7132 100644 --- a/dev/tests/functional/credentials.xml.dist +++ b/dev/tests/functional/credentials.xml.dist @@ -28,14 +28,6 @@ <field replace="carriers_dhl_password_eu" value="" /> <field replace="carriers_dhl_account_eu" value="" /> - <field replace="payment_authorizenet_login" value="" /> - <field replace="payment_authorizenet_trans_key" value="" /> - <field replace="payment_authorizenet_trans_md5" value="" /> - - <field replace="authorizenet_fraud_review_login" value="" /> - <field replace="authorizenet_fraud_review_trans_key" value="" /> - <field replace="authorizenet_fraud_review_md5" value="" /> - <field replace="braintree_enabled_fraud_merchant_account_id" value="" /> <field replace="braintree_enabled_fraud_merchant_id" value="" /> <field replace="braintree_enabled_fraud_public_key" value="" /> diff --git a/dev/tests/functional/etc/repository_replacer_payments.xml b/dev/tests/functional/etc/repository_replacer_payments.xml index 2b20e7220f537..5141280399e42 100644 --- a/dev/tests/functional/etc/repository_replacer_payments.xml +++ b/dev/tests/functional/etc/repository_replacer_payments.xml @@ -14,11 +14,4 @@ <field name="privateKey" xsi:type="string">BRAINTREE_PRIVATE_KEY</field> </dataset> </repository> - - <repository class="Magento\Authorizenet\Test\Repository\AuthorizenetSandboxCustomer"> - <dataset name="sandbox_fraud_hold_review"> - <field name="login_id" xsi:type="string">AUTHORIZENET_LOGIN_ID</field> - <field name="password" xsi:type="string">AUTHORIZENET_PASSWORD</field> - </dataset> - </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.xml index 739aaf3b1e1c3..bd090ad18a26f 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.xml @@ -9,6 +9,7 @@ <testCase name="Magento\Integration\Test\TestCase\ReAuthorizeTokensIntegrationEntityTest" summary="Re-Authorize Tokens for the Integration" ticketId="MAGETWO-29648"> <variation name="ReAuthorizeTokensIntegrationEntityTestVariation1"> <data name="description" xsi:type="string">Re-authorize integration</data> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <constraint name="Magento\Integration\Test\Constraint\AssertIntegrationSuccessReauthorizeMessage" /> <constraint name="Magento\Integration\Test\Constraint\AssertIntegrationTokensAfterReauthorize" /> </variation> diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml index 8ae10e1314b07..97b31c5d6502d 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.xml @@ -18,6 +18,7 @@ <constraint name="Magento\Integration\Test\Constraint\AssertIntegrationSuccessSaveMessage" /> <constraint name="Magento\Integration\Test\Constraint\AssertIntegrationForm" /> <constraint name="Magento\Integration\Test\Constraint\AssertIntegrationInGrid" /> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> </variation> <variation name="UpdateIntegrationEntityTestVariation2"> <data name="tag" xsi:type="string">stable:no</data> @@ -41,6 +42,7 @@ <data name="integration/data/resource_access" xsi:type="string">Custom</data> <data name="integration/data/resources" xsi:type="string">Sales</data> <constraint name="Magento\Integration\Test\Constraint\AssertIncorrectUserPassword" /> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.xml index ce91de81459f1..27d2a1ba5b3f3 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.xml @@ -15,6 +15,7 @@ <data name="template/data/text" xsi:type="string">Some content %isolation%</data> <constraint name="Magento\Newsletter\Test\Constraint\AssertNewsletterSuccessCreateMessage" /> <constraint name="Magento\Newsletter\Test\Constraint\AssertNewsletterInGrid" /> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.xml index 456d9a91b1171..b6b40f43cc3e3 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.xml @@ -16,6 +16,7 @@ <constraint name="Magento\Newsletter\Test\Constraint\AssertNewsletterSuccessCreateMessage" /> <constraint name="Magento\Newsletter\Test\Constraint\AssertNewsletterInGrid" /> <constraint name="Magento\Newsletter\Test\Constraint\AssertNewsletterForm" /> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml index d2bf309e68902..f1da612aa6ca0 100644 --- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml @@ -8,20 +8,20 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sitemap\Test\TestCase\CreateSitemapEntityTest" summary="Create Sitemap" ticketId="MAGETWO-23277"> <variation name="CreateSitemapEntityTestVariation1"> - <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data> + <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1,mftf_migrated:yes</data> <data name="sitemap/data/sitemap_filename" xsi:type="string">sitemap.xml</data> <data name="sitemap/data/sitemap_path" xsi:type="string">/</data> <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessSaveMessage" /> <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapInGrid" /> </variation> <variation name="CreateSitemapEntityTestVariation2"> - <data name="tag" xsi:type="string">severity:S3</data> + <data name="tag" xsi:type="string">severity:S3,mftf_migrated:yes</data> <data name="sitemap/data/sitemap_filename" xsi:type="string">%isolation%</data> <data name="sitemap/data/sitemap_path" xsi:type="string">/</data> <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapFailPathSaveMessage" /> </variation> <variation name="CreateSitemapEntityTestVariation3"> - <data name="tag" xsi:type="string">severity:S3</data> + <data name="tag" xsi:type="string">severity:S3,mftf_migrated:yes</data> <data name="sitemap/data/sitemap_filename" xsi:type="string">sitemap.xml</data> <data name="sitemap/data/sitemap_path" xsi:type="string">/%isolation%</data> <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapFailFolderSaveMessage" /> diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml index a520fa573e1b9..eeb000bd6a803 100644 --- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Sitemap\Test\TestCase\DeleteSitemapEntityTest" summary="Delete Sitemap Entity" ticketId="MAGETWO-23296"> <variation name="DeleteSitemapEntityTestVariation1"> - <data name="tag" xsi:type="string">severity:S2</data> + <data name="tag" xsi:type="string">severity:S2,mftf_migrated:yes</data> <data name="sitemap/dataset" xsi:type="string">default</data> <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessDeleteMessage" /> <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapNotInGrid" /> diff --git a/dev/tests/integration/framework/Magento/TestFramework/Downloadable/Model/RemoveLinkPurchasedByOrderIncrementId.php b/dev/tests/integration/framework/Magento/TestFramework/Downloadable/Model/RemoveLinkPurchasedByOrderIncrementId.php new file mode 100644 index 0000000000000..7f27ab0932b42 --- /dev/null +++ b/dev/tests/integration/framework/Magento/TestFramework/Downloadable/Model/RemoveLinkPurchasedByOrderIncrementId.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\TestFramework\Downloadable\Model; + +use Magento\Downloadable\Model\ResourceModel\Link\Purchased as PurchasedResource; +use Magento\Downloadable\Model\ResourceModel\Link\Purchased\CollectionFactory; + +/** + * Delete records from downloadable_link_purchased associated with provided order + */ +class RemoveLinkPurchasedByOrderIncrementId +{ + /** @var CollectionFactory */ + private $linkCollectionFactory; + + /** @var PurchasedResource */ + private $purchasedResource; + + /** + * @param CollectionFactory $linkCollectionFactory + * @param PurchasedResource $purchasedResource + */ + public function __construct(CollectionFactory $linkCollectionFactory, PurchasedResource $purchasedResource) + { + $this->linkCollectionFactory = $linkCollectionFactory; + $this->purchasedResource = $purchasedResource; + } + + /** + * Remove records from downloadable_link_purchased related to provided order + * + * @param string $orderIncrementId + * @return void + */ + public function execute(string $orderIncrementId): void + { + $collection = $this->linkCollectionFactory->create(); + $collection->addFieldToFilter('order_increment_id', $orderIncrementId); + foreach ($collection as $item) { + $this->purchasedResource->delete($item); + } + } +} diff --git a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php index feb9eca0793a2..d2a6bb7da9abd 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php +++ b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php @@ -7,21 +7,25 @@ /** * Abstract class for the controller tests */ + namespace Magento\TestFramework\TestCase; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\App\ResponseInterface; use Magento\Framework\Data\Form\FormKey; use Magento\Framework\Message\MessageInterface; use Magento\Framework\Stdlib\CookieManagerInterface; use Magento\Framework\View\Element\Message\InterpretationStrategyInterface; use Magento\Theme\Controller\Result\MessagePlugin; -use Magento\Framework\App\Request\Http as HttpRequest; -use Magento\Framework\App\Response\Http as HttpResponse; +use PHPUnit\Framework\TestCase; /** + * Set of methods useful for performing requests to Controllers. + * * @SuppressWarnings(PHPMD.NumberOfChildren) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -abstract class AbstractController extends \PHPUnit\Framework\TestCase +abstract class AbstractController extends TestCase { protected $_runCode = ''; @@ -30,12 +34,12 @@ abstract class AbstractController extends \PHPUnit\Framework\TestCase protected $_runOptions = []; /** - * @var \Magento\Framework\App\RequestInterface + * @var RequestInterface */ protected $_request; /** - * @var \Magento\Framework\App\ResponseInterface + * @var ResponseInterface */ protected $_response; @@ -103,8 +107,9 @@ protected function assertPostConditions() */ public function dispatch($uri) { - /** @var HttpRequest $request */ $request = $this->getRequest(); + + $request->setDispatched(false); $request->setRequestUri($uri); if ($request->isPost() && !array_key_exists('form_key', $request->getPost()) @@ -119,25 +124,36 @@ public function dispatch($uri) /** * Request getter * - * @return \Magento\Framework\App\RequestInterface|HttpRequest + * @return RequestInterface */ public function getRequest() { if (!$this->_request) { - $this->_request = $this->_objectManager->get(\Magento\Framework\App\RequestInterface::class); + $this->_request = $this->_objectManager->get(RequestInterface::class); } return $this->_request; } + /** + * Reset Request parameters + * + * @return void + */ + protected function resetRequest(): void + { + $this->_objectManager->removeSharedInstance(RequestInterface::class); + $this->_request = null; + } + /** * Response getter * - * @return \Magento\Framework\App\ResponseInterface|HttpResponse + * @return ResponseInterface */ public function getResponse() { if (!$this->_response) { - $this->_response = $this->_objectManager->get(\Magento\Framework\App\ResponseInterface::class); + $this->_response = $this->_objectManager->get(ResponseInterface::class); } return $this->_response; } diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTest.php deleted file mode 100644 index 1b8b1b716ce5f..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTest.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment; - -use Magento\Authorizenet\Model\Directpost; -use Magento\Backend\App\Action\Context as BackendActionContext; -use Magento\Backend\Model\Session\Quote as SessionQuote; -use Magento\Backend\Model\UrlInterface; -use Magento\Framework\Json\Helper\Data as JsonHelper; -use Magento\Framework\ObjectManagerInterface; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\Quote\Model\Quote; -use Magento\Quote\Model\Quote\Payment; -use Magento\Sales\Model\AdminOrder\Create as AdminOrderCreate; -use Magento\Sales\Model\Order; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\TestCase\AbstractBackendController; -use PHPUnit\Framework\MockObject\MockObject; - -/** - * Verify AuthorizeNet Controller for PlaceOrder - * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class PlaceTest extends AbstractBackendController -{ - /** - * Test requestToAuthorizenetData returning - * @magentoAppArea adminhtml - */ - public function testExecuteAuthorizenetDataReturning() - { - $requestToAuthorizenetData = ['Authorizenet' => 'data']; - - $this->getRequest()->setParam('payment', ['method' => 'authorizenet_directpost']); - $this->getRequest()->setParam('controller', 'order_create'); - $orderCreateMock = $this->getOrderCreateMock($requestToAuthorizenetData); - $directpostMock = $this->getMockBuilder(Directpost::class) - ->setMethods(['getCode']) - ->disableOriginalConstructor() - ->getMock(); - $directpostMock->expects($this->once()) - ->method('getCode') - ->willReturn('authorizenet_directpost'); - $jsonHelper = $this->_objectManager->get(JsonHelper::class); - $objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class) - ->setMethods(['create', 'get']) - ->getMockForAbstractClass(); - $objectManagerMock->expects($this->atLeastOnce()) - ->method('create') - ->with(Directpost::class) - ->willReturn($directpostMock); - $authorizenetSessionMock = $this->getMockBuilder(Directpost::class) - ->disableOriginalConstructor() - ->getMock(); - $urlMock = $this->getMockBuilder(UrlInterface::class) - ->getMockForAbstractClass(); - $objectManagerMock->expects($this->atLeastOnce()) - ->method('get') - ->willReturnMap([ - [AdminOrderCreate::class, $orderCreateMock], - [JsonHelper::class, $jsonHelper], - [Directpost\Session::class, $authorizenetSessionMock], - [UrlInterface::class, $urlMock], - ]); - - $context = $this->getObjectManager()->create( - BackendActionContext::class, - [ - 'objectManager' => $objectManagerMock - ] - ); - - $controller = $this->getObjectManager()->create( - PlaceTesting::class, - ['context' => $context] - ); - $controller->execute(); - $this->assertContains(json_encode($requestToAuthorizenetData), $this->getResponse()->getBody()); - } - - /** - * @param array $requestToAuthorizenetData - * @return AdminOrderCreate|MockObject - */ - private function getOrderCreateMock($requestToAuthorizenetData) - { - $methodInstanceMock = $this->getMockBuilder(Directpost::class) - ->disableOriginalConstructor() - ->getMock(); - $directpostRequestMock = $this->getMockBuilder(Directpost\Request::class) - ->setMethods(['getData']) - ->disableOriginalConstructor() - ->getMock(); - $directpostRequestMock->expects($this->once()) - ->method('getData') - ->willReturn($requestToAuthorizenetData); - $methodInstanceMock->expects($this->once()) - ->method('generateRequestFromOrder') - ->willReturn($directpostRequestMock); - $paymentMock = $this->getMockBuilder(Payment::class) - ->setMethods(['getMethod', 'getMethodInstance']) - ->disableOriginalConstructor() - ->getMock(); - $paymentMock->expects($this->once()) - ->method('getMethod') - ->willReturn('authorizenet_directpost'); - $paymentMock->expects($this->once()) - ->method('getMethodInstance') - ->willReturn($methodInstanceMock); - $quoteMock = $this->getMockBuilder(Quote::class) - ->setMethods(['getPayment', 'getStoreId']) - ->disableOriginalConstructor() - ->getMock(); - $quoteMock->expects($this->any()) - ->method('getPayment') - ->willReturn($paymentMock); - $orderMock = $this->getMockBuilder(Order::class) - ->setMethods(['getPayment']) - ->disableOriginalConstructor() - ->getMock(); - $orderMock->expects($this->any()) - ->method('getPayment') - ->willReturn($paymentMock); - $sessionQuoteMock = $this->getMockBuilder(SessionQuote::class) - ->setMethods(['getOrder']) - ->disableOriginalConstructor() - ->getMock(); - $sessionQuoteMock->expects($this->once()) - ->method('getOrder') - ->willReturn($orderMock); - $orderCreateMock = $this->getMockBuilder(AdminOrderCreate::class) - ->setMethods(['getQuote', 'getSession', 'setIsValidate', 'importPostData', 'createOrder', 'setPaymentData']) - ->disableOriginalConstructor() - ->getMock(); - $orderCreateMock->expects($this->any()) - ->method('getQuote') - ->willReturn($quoteMock); - $orderCreateMock->expects($this->once()) - ->method('getSession') - ->willReturn($sessionQuoteMock); - $orderCreateMock->expects($this->once()) - ->method('setIsValidate') - ->willReturnSelf(); - $orderCreateMock->expects($this->once()) - ->method('importPostData') - ->willReturnSelf(); - $orderCreateMock->expects($this->once()) - ->method('createOrder') - ->willReturn($orderMock); - - return $orderCreateMock; - } - - /** - * @return ObjectManagerInterface - */ - private function getObjectManager(): ObjectManagerInterface - { - return Bootstrap::getObjectManager(); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTesting.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTesting.php deleted file mode 100644 index cb13f81381fde..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTesting.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment; - -/** - * Class PlaceTesting extended test class, used to substitute calls to parent methods - */ -class PlaceTesting extends Place -{ - /** - * {@inheritdoc} - * This method tested in Magento\Sales\Controller\Adminhtml\Order\CreateTest - */ - protected function _processActionData($action = null) - { - // - } -} diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponseTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponseTest.php deleted file mode 100644 index 7ab55dc7fd928..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponseTest.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Authorizenet\Controller\Directpost\Payment; - -use Magento\TestFramework\TestCase\AbstractController; - -class BackendResponseTest extends AbstractController -{ - /** - * @var string - */ - private static $entryPoint = 'authorizenet/directpost_payment/backendresponse'; - - /** - * Checks a test case when request is processed from different to Authorize.net entry point. - */ - public function testUnauthorizedRequest() - { - $data = [ - 'x_response_code' => 1, - 'x_response_reason_code' => 1, - 'x_invoice_num' => '1', - 'x_amount' => 16, - 'x_trans_id' => '32iiw5ve', - 'x_card_type' => 'American Express', - 'x_account_number' => 'XXXX0002', - 'x_MD5_Hash' => 'h6a4s2h' - ]; - $this->getRequest()->setPostValue($data); - $this->dispatch(self::$entryPoint); - - self::assertEquals(302, $this->getResponse()->getHttpResponseCode()); - self::assertEmpty($this->getResponse()->getBody()); - } - - /** - * Checks a test case when request is successfully processed. - * - * @magentoConfigFixture current_store payment/authorizenet_directpost/trans_md5 n4v2c5n0d - * @magentoConfigFixture current_store payment/authorizenet_directpost/login merch1 - */ - public function testSuccess() - { - $data = [ - 'x_response_code' => 1, - 'x_response_reason_code' => 1, - 'x_invoice_num' => '1', - 'x_amount' => 16, - 'x_trans_id' => '32iiw5ve', - 'x_card_type' => 'American Express', - 'x_account_number' => 'XXXX0002', - 'x_MD5_Hash' => '0EAD2F65D3D879CCB0D1A6F24883AC92' - ]; - $this->getRequest()->setPostValue($data); - $this->dispatch(self::$entryPoint); - self::assertEquals(200, $this->getResponse()->getHttpResponseCode()); - self::assertContains('/sales/order/view', $this->getResponse()->getBody()); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/Payment/ResponseTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/Payment/ResponseTest.php deleted file mode 100644 index 043bae9f2417b..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/Payment/ResponseTest.php +++ /dev/null @@ -1,245 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Authorizenet\Controller\Directpost\Payment; - -/** - * Class ResponseTest - * - * @magentoAppArea frontend - */ -class ResponseTest extends \Magento\TestFramework\TestCase\AbstractController -{ - /** - * Tests the controller for declines - * - * @param int $invoiceNum - * @param string $hash - * @param string $errorMsg - * @param string[] $params - * - * @dataProvider responseActionAuthorizeCaptureDeclineDataProvider - */ - public function testResponseActionAuthorizeCaptureDecline($invoiceNum, $hash, $errorMsg, $params) - { - $controllerName = 'directpost_payment'; - $controllerModule = 'authorizenet'; - $controllerAction = 'response'; - $params['x_invoice_num'] = $invoiceNum; - $params['x_MD5_Hash'] = $hash; - $this->getRequest()->setControllerName( - $controllerName - )->setControllerModule( - $controllerModule - )->setActionName( - $controllerAction - )->setRouteName( - $controllerModule - )->setRequestUri("/{$controllerModule}/{$controllerName}/{$controllerAction}") - ->setParams($params); - - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - - /** @var \Magento\Authorizenet\Controller\Directpost\Payment\Response */ - $controller = $objectManager->create(\Magento\Authorizenet\Controller\Directpost\Payment\Response::class); - - $response = $controller->execute(); - $output = $response->getLayout()->getOutput(); - - $expectedString = "{$controllerModule}/{$controllerName}/redirect/x_invoice_num/{$params['x_invoice_num']}/" - . "success/0/error_msg/{$errorMsg}/controller_action_name/{$controllerName}/"; - - $this->assertContains('window.location', $output); - $this->assertContains($expectedString, $output); - } - - /** - * Tests the controller for created blocks used for sending emails that should not affect layout response - * - * @param string $hash - * @param string[] $params - * - * @dataProvider responseActionAuthorizeCaptureSuccessDataProvider - */ - public function testBlockCreationAffectingResult($hash, $params) - { - $controllerName = 'directpost_payment'; - $controllerModule = 'authorizenet'; - $controllerAction = 'response'; - $params['x_invoice_num'] = 100000002; - $params['x_MD5_Hash'] = $hash; - $this->getRequest()->setControllerName( - $controllerName - )->setControllerModule( - $controllerModule - )->setActionName( - $controllerAction - )->setRouteName( - $controllerModule - )->setRequestUri("/{$controllerModule}/{$controllerName}/{$controllerAction}") - ->setParams($params); - - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - - $directpostMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost::class) - ->disableOriginalConstructor() - ->getMock(); - $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManagerInterface::class) - ->setMethods(['create']) - ->getMockForAbstractClass(); - $objectManagerMock->expects($this->atLeastOnce()) - ->method('create') - ->with(\Magento\Authorizenet\Model\Directpost::class) - ->willReturn($directpostMock); - $context = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Backend\App\Action\Context::class, - [ - 'objectManager' => $objectManagerMock - ] - ); - - /** @var \Magento\Authorizenet\Controller\Directpost\Payment\Response $controller */ - $controller = $objectManager->create( - \Magento\Authorizenet\Controller\Directpost\Payment\Response::class, - [ - 'context' => $context - ] - ); - - // create one block for potential layout stack modification that should not affect response - /** @var \Magento\Authorizenet\Block\Adminhtml\Order\View\Info\FraudDetails $block */ - $block = $objectManager->get(\Magento\Framework\View\LayoutInterface::class) - ->createBlock(\Magento\Authorizenet\Block\Adminhtml\Order\View\Info\FraudDetails::class); - $block->setTemplate('Magento_Payment::order/view/info/fraud_details.phtml'); - - $response = $controller->execute(); - $output = $response->getLayout()->getOutput(); - - $expectedString = "{$controllerModule}/{$controllerName}/redirect/x_invoice_num/{$params['x_invoice_num']}/" - . "success/1/controller_action_name/{$controllerName}/"; - - $this->assertContains('window.location', $output); - $this->assertContains($expectedString, $output); - } - - /** - * @return array - */ - public function responseActionAuthorizeCaptureDeclineDataProvider() - { - $postArray = [ - 'x_response_code' => 1, - 'x_response_reason_code' => 1, - 'x_response_reason_text' => 'This transaction has been approved.', - 'x_avs_code' => 'Y', - 'x_auth_code' => 'G0L0XR', - 'x_trans_id' => '60016479791', - 'x_method' => 'CC', - 'x_card_type' => 'American Express', - 'x_account_number' => 'XXXX0002', - 'x_first_name' => 'Name', - 'x_last_name' => 'Surname', - 'x_company' => null, - 'x_address' => 'Address', - 'x_city' => 'Austin', - 'x_state' => 'Texas', - 'x_zip' => '78753', - 'x_country' => 'US', - 'x_phone' => '5127242323', - 'x_fax' => null, - 'x_email' => 'customer@example.com', - 'x_description' => null, - 'x_type' => 'auth_capture', - 'x_cust_id' => null, - 'x_ship_to_first_name' => null, - 'x_ship_to_last_name' => null, - 'x_ship_to_company' => null, - 'x_ship_to_address' => null, - 'x_ship_to_city' => null, - 'x_ship_to_state' => null, - 'x_ship_to_zip' => null, - 'x_ship_to_country' => null, - 'x_amount' => 100.00, - 'x_tax' => 0.00, - 'x_duty' => 0.00, - 'x_freight' => 0.00, - 'x_tax_exempt' => false, - 'x_po_num' => null, - 'x_SHA2_Hash' => null, - 'x_cvv2_resp_code' => 'P', - 'x_cavv_response' => 2, - 'x_test_request' => false, - 'controller_action_name' => 'directpost_payment', - 'is_secure' => null - ]; - return [ - 'error_hash' => [ - 'invoice_num' => '1231231', - 'x_MD5_Hash' => 'F9AE81A5DA36057D1312D71C904FCCF2', - 'error_msg' => 'The%20transaction%20was%20declined%20because%20the%20' - . 'response%20hash%20validation%20failed.', - 'post' => $postArray - ] - ]; - } - - /** - * @return array - */ - public function responseActionAuthorizeCaptureSuccessDataProvider() - { - $postArray = [ - 'x_response_code' => 1, - 'x_response_reason_code' => 1, - 'x_response_reason_text' => 'This transaction has been approved.', - 'x_avs_code' => 'Y', - 'x_auth_code' => 'G0L0XR', - 'x_trans_id' => '60016479791', - 'x_method' => 'CC', - 'x_card_type' => 'American Express', - 'x_account_number' => 'XXXX0002', - 'x_first_name' => 'Name', - 'x_last_name' => 'Surname', - 'x_company' => null, - 'x_address' => 'Address', - 'x_city' => 'Austin', - 'x_state' => 'Texas', - 'x_zip' => '78753', - 'x_country' => 'US', - 'x_phone' => '5127242323', - 'x_fax' => null, - 'x_email' => 'integrationtest@magento.com', - 'x_description' => null, - 'x_type' => 'auth_capture', - 'x_cust_id' => null, - 'x_ship_to_first_name' => null, - 'x_ship_to_last_name' => null, - 'x_ship_to_company' => null, - 'x_ship_to_address' => null, - 'x_ship_to_city' => null, - 'x_ship_to_state' => null, - 'x_ship_to_zip' => null, - 'x_ship_to_country' => null, - 'x_amount' => 120.15, - 'x_tax' => 0.00, - 'x_duty' => 0.00, - 'x_freight' => 0.00, - 'x_tax_exempt' => false, - 'x_po_num' => null, - 'x_SHA2_Hash' => null, - 'x_cvv2_resp_code' => 'P', - 'x_cavv_response' => 2, - 'x_test_request' => false, - 'controller_action_name' => 'directpost_payment', - 'is_secure' => null - ]; - return [ - 'success' => [ - 'x_MD5_Hash' => '35DCF749F7760193FB8254886E1D1522', - 'post' => $postArray - ], - ]; - } -} diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/PaymentTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/PaymentTest.php deleted file mode 100644 index f6ca9db995023..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/PaymentTest.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Authorizenet\Controller\Directpost; - -/** - * Class PaymentTest - */ -class PaymentTest extends \Magento\TestFramework\TestCase\AbstractController -{ - public function testResponseActionValidationFailed() - { - $this->getRequest()->setPostValue('controller_action_name', 'onepage'); - $this->dispatch('authorizenet/directpost_payment/response'); - // @codingStandardsIgnoreStart - $this->assertContains( - 'authorizenet/directpost_payment/redirect/success/0/error_msg/The%20transaction%20was' - . '%20declined%20because%20the%20response%20hash%20validation%20failed.', - // @codingStandardsIgnoreEnd - $this->getResponse()->getBody() - ); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/Directpost/RequestTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/Directpost/RequestTest.php deleted file mode 100644 index 8f3cce9679953..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/Directpost/RequestTest.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Authorizenet\Model\Directpost; - -use Magento\Authorizenet\Model\Directpost; -use Magento\Framework\Api\FilterBuilder; -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\App\ObjectManager; -use Magento\Sales\Api\Data\OrderInterface; -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\Order; -use Magento\TestFramework\Helper\Bootstrap; -use PHPUnit\Framework\MockObject_MockObject as MockObject; - -/** - * Class contains tests for Authorize.net Direct Post request handler - */ -class RequestTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var Order - */ - private $order; - - /** - * @var Request - */ - private $request; - - /** - * @var ObjectManager - */ - private $objectManager; - - protected function setUp() - { - $this->objectManager = Bootstrap::getObjectManager(); - - $this->order = $this->getOrder(); - $this->request = $this->objectManager->get(Request::class); - } - - /** - * @covers \Magento\Authorizenet\Model\Directpost\Request::setDataFromOrder - * @magentoDataFixture Magento/Authorizenet/_files/order.php - */ - public function testSetDataFromOrder() - { - $customerEmail = 'john.doe@example.com'; - $merchantEmail = 'merchant@example.com'; - - /** @var Directpost|MockObject $payment */ - $payment = $this->getMockBuilder(Directpost::class) - ->disableOriginalConstructor() - ->setMethods(['getConfigData']) - ->getMock(); - - $payment->expects(static::exactly(2)) - ->method('getConfigData') - ->willReturnMap([ - ['email_customer', null, $customerEmail], - ['merchant_email', null, $merchantEmail] - ]); - - $result = $this->request->setDataFromOrder($this->order, $payment); - - static::assertEquals('US', $result->getXCountry()); - static::assertEquals('UK', $result->getXShipToCountry()); - static::assertEquals($customerEmail, $result->getXEmailCustomer()); - static::assertEquals($merchantEmail, $result->getXMerchantEmail()); - } - - /** - * Get stored order - * @return Order - */ - private function getOrder() - { - /** @var FilterBuilder $filterBuilder */ - $filterBuilder = $this->objectManager->get(FilterBuilder::class); - $filters = [ - $filterBuilder->setField(OrderInterface::INCREMENT_ID) - ->setValue('100000002') - ->create() - ]; - - /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ - $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class); - $searchCriteria = $searchCriteriaBuilder->addFilters($filters) - ->create(); - - $orderRepository = $this->objectManager->get(OrderRepositoryInterface::class); - $orders = $orderRepository->getList($searchCriteria) - ->getItems(); - - /** @var OrderInterface $order */ - return array_pop($orders); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php deleted file mode 100644 index ba4c4efd78f1b..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/Model/DirectpostTest.php +++ /dev/null @@ -1,252 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Authorizenet\Model; - -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\App\ObjectManager; -use Magento\Framework\HTTP\ZendClient; -use Magento\Framework\HTTP\ZendClientFactory; -use Magento\Framework\Simplexml\Element; -use Magento\Sales\Api\Data\OrderInterface; -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\Order; -use Magento\Sales\Model\Order\Payment; -use Magento\TestFramework\Helper\Bootstrap; -use PHPUnit_Framework_MockObject_MockObject as MockObject; - -/** - * Class contains tests for Direct Post integration - * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class DirectpostTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var ObjectManager - */ - private $objectManager; - - /** - * @var ZendClientFactory|MockObject - */ - private $httpClientFactory; - - /** - * @var Directpost - */ - private $directPost; - - protected function setUp() - { - $this->objectManager = Bootstrap::getObjectManager(); - - $this->httpClientFactory = $this->getMockBuilder(ZendClientFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $this->directPost = $this->objectManager->create(Directpost::class, [ - 'httpClientFactory' => $this->httpClientFactory - ]); - } - - /** - * @covers \Magento\Authorizenet\Model\Directpost::capture - * @magentoDataFixture Magento/Authorizenet/_files/order.php - */ - public function testCapture() - { - $amount = 120.15; - /** @var Payment $payment */ - $payment = $this->getPayment('100000002'); - $transactionId = '106235225'; - - /** @var ZendClient|MockObject $httpClient */ - $httpClient = $this->getMockBuilder(ZendClient::class) - ->disableOriginalConstructor() - ->setMethods(['setUri', 'setConfig', 'setParameterPost', 'setMethod', 'request']) - ->getMock(); - - $this->httpClientFactory->expects(static::once()) - ->method('create') - ->willReturn($httpClient); - - $response = $this->getMockBuilder('Zend_Http_Response') - ->disableOriginalConstructor() - ->setMethods(['getBody']) - ->getMock(); - $response->expects(static::once()) - ->method('getBody') - ->willReturn( - "1(~)1(~)1(~)This transaction has been approved.(~)AWZFTG(~)P(~){$transactionId}(~)100000002(~) - (~)120.15(~)CC(~)prior_auth_capture(~)(~)Anthony(~)Nealy(~)(~)Pearl St(~)Los Angeles(~)California - (~)10020(~)US(~)22-333-44(~)(~)customer@example.com(~)John(~)Doe(~) - (~)Bourne St(~)London(~)(~)DW23W(~)UK(~)0.00(~)(~){$amount}(~)(~) - (~)74B5D54ADFE98093A0FF6446(~)(~)(~)(~)(~)(~)(~)(~)(~)(~)(~)(~)(~)XXXX1111(~)Visa(~)(~)(~)(~)(~) - (~)(~)(~)(~)(~)(~)(~)(~)(~)(~)(~)(~)" - ); - - $httpClient->expects(static::once()) - ->method('request') - ->willReturn($response); - - $this->directPost->capture($payment, $amount); - - static::assertEquals($transactionId, $payment->getTransactionId()); - static::assertFalse($payment->getIsTransactionClosed()); - static::assertEquals('US', $payment->getOrder()->getBillingAddress()->getCountryId()); - static::assertEquals('UK', $payment->getOrder()->getShippingAddress()->getCountryId()); - } - - /** - * Verifies that order is placed in correct state according the action taken for a transaction that - * triggered one or more of the Advanced Fraud Detection Suite filters. - * - * @param string $filterAction - * @param string $orderId - * @param string $expectedOrderState - * - * @magentoConfigFixture current_store payment/authorizenet_directpost/trans_md5 TestHash - * @magentoConfigFixture current_store payment/authorizenet_directpost/login TestLogin - * @magentoDataFixture Magento/Authorizenet/_files/order.php - * @dataProvider fdsFilterActionDataProvider - */ - public function testProcessWithFdsFilterActionReportOnly($filterAction, $orderId, $expectedOrderState) - { - $responseBody = $this->getSuccessResponse($orderId); - $transactionService = $this->getTransactionService($filterAction); - $this->objectManager->addSharedInstance($transactionService, TransactionService::class); - - $this->directPost->process($responseBody); - - /** @var Payment $payment */ - $payment = $this->getPayment($orderId); - $this->objectManager->removeSharedInstance(TransactionService::class); - - static::assertEquals($expectedOrderState, $payment->getOrder()->getState()); - } - - /** - * @return array - */ - public function fdsFilterActionDataProvider() - { - return [ - [ - 'filter_action' => 'authAndHold', - 'order_id' => '100000003', - 'expected_order_state' => Order::STATE_PAYMENT_REVIEW - ], - [ - 'filter_action' => 'report', - 'order_id' => '100000004', - 'expected_order_state' => Order::STATE_COMPLETE - ], - ]; - } - - /** - * @param string $orderId - * @return array - */ - private function getSuccessResponse($orderId) - { - return [ - 'x_response_code' => '1', - 'x_response_reason_code' => '1', - 'x_response_reason_text' => 'This transaction has been approved.', - 'x_avs_code' => 'Y', - 'x_auth_code' => 'YWO2E2', - 'x_trans_id' => '40004862720', - 'x_method' => 'CC', - 'x_card_type' => 'Visa', - 'x_account_number' => 'XXXX1111', - 'x_first_name' => 'John', - 'x_last_name' => 'Smith', - 'x_company' => 'CompanyName', - 'x_address' => 'Green str, 67', - 'x_city' => 'CityM', - 'x_state' => 'Alabama', - 'x_zip' => '93930', - 'x_country' => 'US', - 'x_phone' => '3468676', - 'x_fax' => '04040404', - 'x_email' => 'user_1@example.com', - 'x_invoice_num' => $orderId, - 'x_description' => '', - 'x_type' => 'auth_only', - 'x_cust_id' => '', - 'x_ship_to_first_name' => 'John', - 'x_ship_to_last_name' => 'Smith', - 'x_ship_to_company' => 'CompanyName', - 'x_ship_to_address' => 'Green str, 67', - 'x_ship_to_city' => 'CityM', - 'x_ship_to_state' => 'Alabama', - 'x_ship_to_zip' => '93930', - 'x_ship_to_country' => 'US', - 'x_amount' => '120.15', - 'x_tax' => '0.00', - 'x_duty' => '0.00', - 'x_freight' => '5.00', - 'x_tax_exempt' => 'FALSE', - 'x_po_num' => '', - 'x_MD5_Hash' => 'C1CC5AB9D6F0481E240AD74DFF624584', - 'x_SHA2_Hash' => '', - 'x_cvv2_resp_code' => 'P', - 'x_cavv_response' => '2', - 'x_test_request' => 'false', - 'controller_action_name' => 'directpost_payment', - 'is_secure' => '1', - ]; - } - - /** - * Get order payment. - * - * @param string $orderId - * @return Payment - */ - private function getPayment($orderId) - { - /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ - $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class); - $searchCriteria = $searchCriteriaBuilder->addFilter(OrderInterface::INCREMENT_ID, $orderId) - ->create(); - - $orderRepository = $this->objectManager->get(OrderRepositoryInterface::class); - $orders = $orderRepository->getList($searchCriteria) - ->getItems(); - - /** @var OrderInterface $order */ - $order = array_pop($orders); - return $order->getPayment(); - } - - /** - * Returns TransactionService mocked object with authorize predefined response. - * - * @param string $filterAction - * @return TransactionService|MockObject - */ - private function getTransactionService($filterAction) - { - $response = str_replace( - '{filterAction}', - $filterAction, - file_get_contents(__DIR__ . '/../_files/transaction_details.xml') - ); - - $transactionService = $this->getMockBuilder(TransactionService::class) - ->disableOriginalConstructor() - ->getMock(); - $transactionService->method('getTransactionDetails') - ->willReturn( - new Element($response) - ); - - return $transactionService; - } -} diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/_files/order.php b/dev/tests/integration/testsuite/Magento/Authorizenet/_files/order.php deleted file mode 100644 index b8d632f3a87af..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/_files/order.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\Order; -use Magento\Sales\Model\Order\Address; -use Magento\Sales\Model\Order\Payment; -use Magento\TestFramework\Helper\Bootstrap; - -$objectManager = Bootstrap::getObjectManager(); - -$amount = 120.15; - -/** @var Payment $payment */ -$payment = $objectManager->create(Payment::class); -$payment - ->setMethod('authorizenet_directpost') - ->setAnetTransType('AUTH_ONLY') - ->setBaseAmountAuthorized($amount) - ->setPoNumber('10101200'); - -/** @var Address\ $billingAddress */ -$billingAddress = $objectManager->create(Address::class, [ - 'data' => [ - 'firstname' => 'John', - 'lastname' => 'Doe', - 'email' => 'customer@example.com', - 'street' => 'Pearl St', - 'city' => 'Los Angeles', - 'region' => 'CA', - 'postcode' => '10020', - 'country_id' => 'US', - 'telephone' => '22-333-44', - 'address_type' => 'billing' - ] -]); - -$shippingAddress = $objectManager->create(Address::class, [ - 'data' => [ - 'firstname' => 'John', - 'lastname' => 'Doe', - 'email' => 'customer@example.com', - 'street' => 'Bourne St', - 'city' => 'London', - 'postcode' => 'DW23W', - 'country_id' => 'UK', - 'telephone' => '22-333-44', - 'address_type' => 'billing' - ] -]); - -/** @var Order $order */ -$order = $objectManager->create(Order::class); -$order->setIncrementId('100000002') - ->setQuoteId(2) - ->setIncrementId('100000002') - ->setBaseGrandTotal($amount) - ->setBaseCurrencyCode('USD') - ->setBaseTaxAmount($amount) - ->setBaseShippingAmount($amount) - ->setCustomerEmail('customer@example.com') - ->setBillingAddress($billingAddress) - ->setShippingAddress($shippingAddress) - ->setPayment($payment); - -/** @var OrderRepositoryInterface $orderRepository */ -$orderRepository = $objectManager->get(OrderRepositoryInterface::class); -$orderRepository->save($order); - -$clonedOrder = clone $order; -$clonedOrder->setIncrementId('100000003') - ->setId(null) - ->setBillingAddress($billingAddress->setId(null)) - ->setShippingAddress($shippingAddress->setId(null)) - ->setPayment($payment->setId(null)); -$orderRepository->save($clonedOrder); - -$clonedOrder = clone $order; -$clonedOrder->setIncrementId('100000004') - ->setId(null) - ->setBillingAddress($billingAddress->setId(null)) - ->setShippingAddress($shippingAddress->setId(null)) - ->setPayment($payment->setId(null)); -$orderRepository->save($clonedOrder); diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/_files/transaction_details.xml b/dev/tests/integration/testsuite/Magento/Authorizenet/_files/transaction_details.xml deleted file mode 100644 index 98b9f258b0625..0000000000000 --- a/dev/tests/integration/testsuite/Magento/Authorizenet/_files/transaction_details.xml +++ /dev/null @@ -1,81 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<getTransactionDetailsResponse> - <messages> - <resultCode>Ok</resultCode> - <message> - <code>I00001</code> - <text>Successful.</text> - </message> - </messages> - <transaction> - <transId>40004862720</transId> - <submitTimeUTC>2017-06-12T13:33:10.1Z</submitTimeUTC> - <submitTimeLocal>2017-06-12T06:33:10.1</submitTimeLocal> - <transactionType>authOnlyTransaction</transactionType> - <transactionStatus>authorizedPendingCapture</transactionStatus> - <responseCode>1</responseCode> - <responseReasonCode>1</responseReasonCode> - <responseReasonDescription>Approval</responseReasonDescription> - <authCode>YWO2E2</authCode> - <AVSResponse>Y</AVSResponse> - <cardCodeResponse>P</cardCodeResponse> - <FDSFilterAction>{filterAction}</FDSFilterAction> - <FDSFilters> - <FDSFilter> - <name>Amount Filter</name> - <action>{filterAction}</action> - </FDSFilter> - </FDSFilters> - <order> - <invoiceNumber>100000002</invoiceNumber> - </order> - <authAmount>120.15</authAmount> - <settleAmount>120.15</settleAmount> - <shipping> - <amount>5.00</amount> - </shipping> - <taxExempt>false</taxExempt> - <payment> - <creditCard> - <cardNumber>XXXX1111</cardNumber> - <expirationDate>XXXX</expirationDate> - <cardType>Visa</cardType> - </creditCard> - </payment> - <customer> - <email>user_1@example.com</email> - </customer> - <billTo> - <firstName>John</firstName> - <lastName>Smith</lastName> - <company>CompanyName</company> - <address>Green str, 67</address> - <city>CityM</city> - <state>Alabama</state> - <zip>93930</zip> - <country>US</country> - <phoneNumber>3468676</phoneNumber> - <faxNumber>04040404</faxNumber> - </billTo> - <shipTo> - <firstName>John</firstName> - <lastName>Smith</lastName> - <company>CompanyName</company> - <address>Green str, 67</address> - <city>CityM</city> - <state>Alabama</state> - <zip>93930</zip> - <country>US</country> - </shipTo> - <recurringBilling>false</recurringBilling> - <customerIP>195.14.124.5</customerIP> - <product>Card Not Present</product> - <marketType>eCommerce</marketType> - </transaction> -</getTransactionDetailsResponse> diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/full_order_with_capture.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/full_order_with_capture.php deleted file mode 100644 index 0b1e8196ef007..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/full_order_with_capture.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -use Magento\AuthorizenetAcceptjs\Gateway\Config; -use Magento\Sales\Api\InvoiceRepositoryInterface; -use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\OrderRepository; -use Magento\Sales\Model\Service\InvoiceService; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Sales\Api\TransactionRepositoryInterface; -use Magento\Sales\Model\Order\Payment\Transaction; -use Magento\Sales\Model\Order\Payment\Transaction\BuilderInterface as TransactionBuilder; - -// phpcs:ignore Magento2.Security.IncludeFile.FoundIncludeFile -$order = include __DIR__ . '/../_files/full_order.php'; - -$objectManager = Bootstrap::getObjectManager(); - -/** @var Payment $payment */ -$payment = $order->getPayment(); -$payment->setMethod(Config::METHOD); -$payment->setAuthorizationTransaction(false); -$payment->setParentTransactionId(4321); - -/** @var OrderRepository $orderRepo */ -$orderRepo = $objectManager->get(OrderRepository::class); -$orderRepo->save($order); - -/** @var InvoiceService $invoiceService */ -$invoiceService = $objectManager->get(InvoiceService::class); -$invoice = $invoiceService->prepareInvoice($order); -$invoice->setIncrementId('100000001'); -$invoice->register(); - -/** @var InvoiceRepositoryInterface $invoiceRepository */ -$invoiceRepository = $objectManager->get(InvoiceRepositoryInterface::class); -$invoice = $invoiceRepository->save($invoice); - - -/** @var \Magento\Sales\Model\Order\CreditmemoFactory $creditmemoFactory */ -$creditmemoFactory = $objectManager->get(\Magento\Sales\Model\Order\CreditmemoFactory::class); -$creditmemo = $creditmemoFactory->createByInvoice($invoice, $invoice->getData()); -$creditmemo->setOrder($order); -$creditmemo->setState(Magento\Sales\Model\Order\Creditmemo::STATE_OPEN); -$creditmemo->setIncrementId('100000001'); - -/** @var \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository */ -$creditmemoRepository = $objectManager->get(\Magento\Sales\Api\CreditmemoRepositoryInterface::class); -$creditmemoRepository->save($creditmemo); - -/** @var TransactionBuilder $transactionBuilder */ -$transactionBuilder = $objectManager->create(TransactionBuilder::class); -$transactionAuthorize = $transactionBuilder->setPayment($payment) - ->setOrder($order) - ->setTransactionId(1234) - ->build(Transaction::TYPE_AUTH); -$transactionCapture = $transactionBuilder->setPayment($payment) - ->setOrder($order) - ->setTransactionId(4321) - ->build(Transaction::TYPE_CAPTURE); - -$transactionRepository = $objectManager->create(TransactionRepositoryInterface::class); -$transactionRepository->save($transactionAuthorize); -$transactionRepository->save($transactionCapture); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/full_order_with_capture_rollback.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/full_order_with_capture_rollback.php deleted file mode 100644 index 1a2cb2532fe52..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/full_order_with_capture_rollback.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\TestFramework\ObjectManager; - -$objectManager = ObjectManager::getInstance(); - -/** @var SearchCriteriaBuilder $searchCriteriaBuilder */ -$searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class); -$searchCriteria = $searchCriteriaBuilder->addFilter('increment_id', '100000001') - ->create(); - -/** @var OrderRepositoryInterface $orderRepository */ -$orderRepository = $objectManager->get(OrderRepositoryInterface::class); -$items = $orderRepository->getList($searchCriteria) - ->getItems(); - -foreach ($items as $item) { - $orderRepository->delete($item); -} - -require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php deleted file mode 100644 index b1d0521c9c610..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\Order; -use Magento\Sales\Model\Order\Address; -use Magento\Sales\Model\Order\Item as OrderItem; -use Magento\Store\Model\StoreManagerInterface; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; -use Magento\Sales\Api\TransactionRepositoryInterface; -use Magento\Sales\Model\Order\Payment\Transaction; -use Magento\Sales\Model\Order\Payment\Transaction\BuilderInterface as TransactionBuilder; - -/** @var ObjectManager $objectManager */ -$objectManager = Bootstrap::getObjectManager(); - -$addressData = include __DIR__ . '/../../Sales/_files/address_data.php'; -require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; - -$billingAddress = $objectManager->create(Address::class, ['data' => $addressData]); -$billingAddress->setAddressType('billing'); - -$shippingAddress = clone $billingAddress; -$shippingAddress->setId(null) - ->setAddressType('shipping'); - -/** @var OrderItem $orderItem */ -$orderItem = $objectManager->create(OrderItem::class); -$orderItem->setProductId($product->getId()) - ->setQtyOrdered(2) - ->setBasePrice($product->getPrice()) - ->setPrice($product->getPrice()) - ->setRowTotal($product->getPrice()) - ->setProductType('simple'); - -require __DIR__ . '/payment.php'; - -$order = $objectManager->create(Order::class); -$order->setIncrementId('100000002') - ->setSubtotal($product->getPrice() * 2) - ->setBaseSubtotal($product->getPrice() * 2) - ->setCustomerEmail('admin@example.com') - ->setCustomerIsGuest(true) - ->setBillingAddress($billingAddress) - ->setShippingAddress($shippingAddress) - ->setStoreId( - $objectManager->get(StoreManagerInterface::class)->getStore() - ->getId() - ) - ->addItem($orderItem) - ->setPayment($payment); - -$payment->setParentTransactionId(1234); - -/** @var OrderRepositoryInterface $orderRepository */ -$orderRepository = $objectManager->get(OrderRepositoryInterface::class); -$orderRepository->save($order); - -/** @var TransactionBuilder $transactionBuilder */ -$transactionBuilder = $objectManager->create(TransactionBuilder::class); -$transactionAuthorize = $transactionBuilder->setPayment($payment) - ->setOrder($order) - ->setTransactionId(1234) - ->build(Transaction::TYPE_AUTH); - -$transactionAuthorize->setAdditionalInformation('real_transaction_id', '1234'); - -$transactionRepository = $objectManager->create(TransactionRepositoryInterface::class); -$transactionRepository->save($transactionAuthorize); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_captured.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_captured.php deleted file mode 100644 index 9bfc863df7de5..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_captured.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\Order; -use Magento\Sales\Model\Order\Address; -use Magento\Sales\Model\Order\Item as OrderItem; -use Magento\Store\Model\StoreManagerInterface; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; -use Magento\Sales\Api\TransactionRepositoryInterface; -use Magento\Sales\Model\Order\Payment\Transaction; -use Magento\Sales\Model\Order\Payment\Transaction\BuilderInterface as TransactionBuilder; - -/** @var ObjectManager $objectManager */ -$objectManager = Bootstrap::getObjectManager(); - -$addressData = include __DIR__ . '/../../Sales/_files/address_data.php'; -require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; - -$billingAddress = $objectManager->create(Address::class, ['data' => $addressData]); -$billingAddress->setAddressType('billing'); - -$shippingAddress = clone $billingAddress; -$shippingAddress->setId(null) - ->setAddressType('shipping'); - -/** @var OrderItem $orderItem */ -$orderItem = $objectManager->create(OrderItem::class); -$orderItem->setProductId($product->getId()) - ->setQtyOrdered(2) - ->setBasePrice($product->getPrice()) - ->setPrice($product->getPrice()) - ->setRowTotal($product->getPrice()) - ->setProductType('simple'); - -require __DIR__ . '/payment.php'; - -$order = $objectManager->create(Order::class); -$order->setIncrementId('100000002') - ->setSubtotal($product->getPrice() * 2) - ->setBaseSubtotal($product->getPrice() * 2) - ->setCustomerEmail('admin@example.com') - ->setCustomerIsGuest(true) - ->setBillingAddress($billingAddress) - ->setShippingAddress($shippingAddress) - ->setStoreId( - $objectManager->get(StoreManagerInterface::class)->getStore() - ->getId() - ) - ->addItem($orderItem) - ->setPayment($payment); - -$payment->setParentTransactionId(4321); - -/** @var OrderRepositoryInterface $orderRepository */ -$orderRepository = $objectManager->get(OrderRepositoryInterface::class); -$orderRepository->save($order); - -/** @var TransactionBuilder $transactionBuilder */ -$transactionBuilder = $objectManager->create(TransactionBuilder::class); -$transactionAuthorize = $transactionBuilder->setPayment($payment) - ->setOrder($order) - ->setTransactionId(1234) - ->build(Transaction::TYPE_AUTH); -$transactionCapture = $transactionBuilder->setPayment($payment) - ->setOrder($order) - ->setTransactionId(4321) - ->build(Transaction::TYPE_CAPTURE); - -$transactionRepository = $objectManager->create(TransactionRepositoryInterface::class); -$transactionRepository->save($transactionAuthorize); -$transactionRepository->save($transactionCapture); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_captured_rollback.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_captured_rollback.php deleted file mode 100644 index a2da0b639e98d..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_captured_rollback.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\TestFramework\ObjectManager; - -$objectManager = ObjectManager::getInstance(); - -/** @var SearchCriteriaBuilder $searchCriteriaBuilder */ -$searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class); -$searchCriteria = $searchCriteriaBuilder->addFilter('increment_id', '100000002') - ->create(); - -/** @var OrderRepositoryInterface $orderRepository */ -$orderRepository = $objectManager->get(OrderRepositoryInterface::class); -$items = $orderRepository->getList($searchCriteria) - ->getItems(); - -foreach ($items as $item) { - $orderRepository->delete($item); -} - -require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/payment.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/payment.php deleted file mode 100644 index 5b15e356a7d8d..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/payment.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\AuthorizenetAcceptjs\Gateway\Config; -use Magento\Sales\Model\Order\Payment; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; - -/** @var ObjectManager $objectManager */ -$objectManager = Bootstrap::getObjectManager(); - -/** @var Payment $payment */ -$payment = $objectManager->create(Payment::class); -$payment->setMethod(Config::METHOD); -$payment->setAuthorizationTransaction(true); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/AbstractTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/AbstractTest.php deleted file mode 100644 index f1458a19012f3..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/AbstractTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway; - -use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\App\Area; -use Magento\Framework\HTTP\ZendClient; -use Magento\Framework\HTTP\ZendClientFactory; -use PHPUnit\Framework\MockObject\Builder\InvocationMocker; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; -use Magento\Payment\Gateway\Data\PaymentDataObjectFactory; -use Magento\Quote\Model\Quote\PaymentFactory; -use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\Order; -use Zend_Http_Response; - -abstract class AbstractTest extends TestCase -{ - /** - * @var ObjectManager - */ - protected $objectManager; - - /** - * @var ZendClient|MockObject|InvocationMocker - */ - protected $clientMock; - - /** - * @var PaymentFactory - */ - protected $paymentFactory; - - /** - * @var Zend_Http_Response - */ - protected $responseMock; - - /** - * @throws \Magento\Framework\Exception\LocalizedException - */ - protected function setUp() - { - $bootstrap = Bootstrap::getInstance(); - $bootstrap->loadArea(Area::AREA_FRONTEND); - $this->objectManager = Bootstrap::getObjectManager(); - $this->clientMock = $this->createMock(ZendClient::class); - $this->responseMock = $this->createMock(Zend_Http_Response::class); - $this->clientMock->method('request') - ->willReturn($this->responseMock); - $this->clientMock->method('setUri') - ->with('https://apitest.authorize.net/xml/v1/request.api'); - $clientFactoryMock = $this->createMock(ZendClientFactory::class); - $clientFactoryMock->method('create') - ->willReturn($this->clientMock); - /** @var PaymentDataObjectFactory $paymentFactory */ - $this->paymentFactory = $this->objectManager->get(PaymentDataObjectFactory::class); - $this->objectManager->addSharedInstance($clientFactoryMock, ZendClientFactory::class); - } - - protected function tearDown() - { - $this->objectManager->removeSharedInstance(ZendClientFactory::class); - parent::tearDown(); - } - - protected function getOrderWithIncrementId(string $incrementId): Order - { - /** @var OrderRepositoryInterface $orderRepository */ - $orderRepository = $this->objectManager->get(OrderRepositoryInterface::class); - $searchCriteria = $this->objectManager->get(SearchCriteriaBuilder::class) - ->addFilter('increment_id', $incrementId) - ->create(); - /** @var Order $order */ - $order = current( - $orderRepository->getList($searchCriteria) - ->getItems() - ); - - return $order; - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/AcceptFdsCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/AcceptFdsCommandTest.php deleted file mode 100644 index 394d9de6684c4..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/AcceptFdsCommandTest.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; - -class AcceptFdsCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - */ - public function testAcceptFdsCommand() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('accept_fds'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/accept_fds.php'; - $response = include __DIR__ . '/../../_files/response/generic_success.php'; - - $this->clientMock->expects($this->once()) - ->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->expects($this->once()) - ->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute([ - 'payment' => $paymentDO - ]); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/AuthorizeCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/AuthorizeCommandTest.php deleted file mode 100644 index 9affd80be0600..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/AuthorizeCommandTest.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\Order\Payment\Transaction; - -class AuthorizeCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - */ - public function testAuthorizeCommand() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('authorize'); - - $order = include __DIR__ . '/../../_files/full_order.php'; - $payment = $order->getPayment(); - - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/authorize.php'; - $response = include __DIR__ . '/../../_files/response/authorize.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute([ - 'payment' => $paymentDO, - 'amount' => 100.00 - ]); - - /** @var Payment $payment */ - $rawDetails = [ - 'authCode' => 'abc123', - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '2', - 'accountType' => 'Visa', - ]; - $this->assertSame('1111', $payment->getCcLast4()); - $this->assertSame('Y', $payment->getCcAvsStatus()); - $this->assertFalse($payment->getData('is_transaction_closed')); - - $transactionDetails = $payment->getTransactionAdditionalInfo(); - foreach ($rawDetails as $key => $value) { - $this->assertSame($value, $payment->getAdditionalInformation($key)); - $this->assertSame($value, $transactionDetails[Transaction::RAW_DETAILS][$key]); - } - - $this->assertSame('123456', $payment->getTransactionId()); - $this->assertSame('123456', $transactionDetails['real_transaction_id']); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/CancelCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/CancelCommandTest.php deleted file mode 100644 index aa606a50ae67a..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/CancelCommandTest.php +++ /dev/null @@ -1,62 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; - -class CancelCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - * @dataProvider aliasesProvider - */ - public function testCancelCommand(string $commandName) - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get($commandName); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/void.php'; - $response = include __DIR__ . '/../../_files/response/void.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute([ - 'payment' => $paymentDO - ]); - - /** @var Payment $payment */ - - $this->assertTrue($payment->getIsTransactionClosed()); - $this->assertTrue($payment->getShouldCloseParentTransaction()); - $this->assertArrayNotHasKey('real_transaction_id', $payment->getTransactionAdditionalInfo()); - } - - public function aliasesProvider() - { - return [ - ['cancel'], - ['deny_payment'] - ]; - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/FetchTransactionInfoCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/FetchTransactionInfoCommandTest.php deleted file mode 100644 index 1651dfc7db3d9..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/FetchTransactionInfoCommandTest.php +++ /dev/null @@ -1,184 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; - -class FetchTransactionInfoCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/transactionSyncKeys transId,transactionType - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - */ - public function testTransactionApproved() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('fetch_transaction_information'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/transaction_details_authorized.php'; - $response = include __DIR__ . '/../../_files/response/transaction_details_authorized.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $result = $command->execute([ - 'payment' => $paymentDO - ]); - - $expected = [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction' - ]; - $this->assertSame($expected, $result); - - /** @var Payment $payment */ - $this->assertTrue($payment->getIsTransactionApproved()); - $this->assertFalse($payment->getIsTransactionDenied()); - } - - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * * @magentoConfigFixture default_store payment/authorizenet_acceptjs/transactionSyncKeys transId,transactionType - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - */ - public function testTransactionVoided() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('fetch_transaction_information'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/transaction_details_authorized.php'; - $response = include __DIR__ . '/../../_files/response/transaction_details_voided.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $result = $command->execute([ - 'payment' => $paymentDO - ]); - - $expected = [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction' - ]; - $this->assertSame($expected, $result); - - /** @var Payment $payment */ - $this->assertFalse($payment->getIsTransactionApproved()); - $this->assertTrue($payment->getIsTransactionDenied()); - } - - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/transactionSyncKeys transId,transactionType - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - */ - public function testTransactionDenied() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('fetch_transaction_information'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/transaction_details_authorized.php'; - $response = include __DIR__ . '/../../_files/response/transaction_details_voided.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $result = $command->execute([ - 'payment' => $paymentDO - ]); - - $expected = [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction' - ]; - $this->assertSame($expected, $result); - - /** @var Payment $payment */ - $this->assertFalse($payment->getIsTransactionApproved()); - $this->assertTrue($payment->getIsTransactionDenied()); - } - - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/transactionSyncKeys transId,transactionType - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - */ - public function testTransactionPending() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('fetch_transaction_information'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/transaction_details_authorized.php'; - $response = include __DIR__ . '/../../_files/response/transaction_details_fds_pending.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $result = $command->execute([ - 'payment' => $paymentDO - ]); - - $expected = [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction' - ]; - $this->assertSame($expected, $result); - - /** @var Payment $payment */ - $this->assertNull($payment->getIsTransactionApproved()); - $this->assertNull($payment->getIsTransactionDenied()); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/RefundSettledCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/RefundSettledCommandTest.php deleted file mode 100644 index 0206ecd6b876b..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/RefundSettledCommandTest.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Api\Data\CreditmemoInterface; -use Magento\Sales\Model\Order; -use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\ResourceModel\Order\Creditmemo\CollectionFactory as CreditmemoCollectionFactory; - -class RefundSettledCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/full_order_with_capture.php - */ - public function testRefundSettledCommand() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('refund_settled'); - - $order = $this->getOrderWithIncrementId('100000001'); - $payment = $order->getPayment(); - $payment->setCreditmemo($this->getCreditmemo($order)); - - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/refund.php'; - $response = include __DIR__ . '/../../_files/response/refund.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute( - [ - 'payment' => $paymentDO, - 'amount' => 100.00 - ] - ); - - /** @var Payment $payment */ - $this->assertTrue($payment->getIsTransactionClosed()); - $this->assertSame('5678', $payment->getTransactionId()); - } - - /** - * Retrieve creditmemo from order. - * - * @param Order $order - * @return CreditmemoInterface - */ - private function getCreditmemo(Order $order): CreditmemoInterface - { - /** @var \Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection $creditMemoCollection */ - $creditMemoCollection = $this->objectManager->create(CreditmemoCollectionFactory::class)->create(); - - /** @var CreditmemoInterface $creditMemo */ - $creditMemo = $creditMemoCollection - ->setOrderFilter($order) - ->setPageSize(1) - ->getFirstItem(); - - return $creditMemo; - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/SaleCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/SaleCommandTest.php deleted file mode 100644 index 7ae03d36cb752..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/SaleCommandTest.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\Order\Payment\Transaction; - -class SaleCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - */ - public function testSaleCommand() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('sale'); - - $order = include __DIR__ . '/../../_files/full_order.php'; - $payment = $order->getPayment(); - - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/sale.php'; - $response = include __DIR__ . '/../../_files/response/sale.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute([ - 'payment' => $paymentDO, - 'amount' => 100.00 - ]); - - /** @var Payment $payment */ - $rawDetails = [ - 'authCode' => 'abc123', - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '2', - 'accountType' => 'Visa', - ]; - $this->assertSame('1111', $payment->getCcLast4()); - $this->assertSame('Y', $payment->getCcAvsStatus()); - - $transactionDetails = $payment->getTransactionAdditionalInfo(); - foreach ($rawDetails as $key => $value) { - $this->assertSame($value, $payment->getAdditionalInformation($key)); - $this->assertSame($value, $transactionDetails[Transaction::RAW_DETAILS][$key]); - } - - $this->assertSame('123456', $payment->getTransactionId()); - $this->assertSame('123456', $transactionDetails['real_transaction_id']); - $this->assertTrue($payment->getShouldCloseParentTransaction()); - $this->assertFalse($payment->getData('is_transaction_closed')); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/SettleCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/SettleCommandTest.php deleted file mode 100644 index bb0a259b165bf..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/SettleCommandTest.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; - -class SettleCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - */ - public function testRefundSettledCommand() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('settle'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/settle.php'; - $response = include __DIR__ . '/../../_files/response/settle.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute([ - 'payment' => $paymentDO, - 'amount' => 100.00 - ]); - - /** @var Payment $payment */ - $this->assertTrue($payment->getShouldCloseParentTransaction()); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/TransactionDetailsCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/TransactionDetailsCommandTest.php deleted file mode 100644 index d81cffc413b59..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/TransactionDetailsCommandTest.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; - -class TransactionDetailsCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_captured.php - */ - public function testTransactionDetails() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('get_transaction_details'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/transaction_details.php'; - $response = include __DIR__ . '/../../_files/response/transaction_details_settled_capture.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $result = $command->execute([ - 'payment' => $paymentDO - ]); - - $resultData = $result->get(); - - $this->assertEquals($response, $resultData); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/VoidCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/VoidCommandTest.php deleted file mode 100644 index f74f8542bfdc3..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Command/VoidCommandTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; - -class VoidCommandTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - */ - public function testVoidCommand() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('void'); - - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/void.php'; - $response = include __DIR__ . '/../../_files/response/void.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute([ - 'payment' => $paymentDO - ]); - - /** @var Payment $payment */ - - $this->assertTrue($payment->getIsTransactionClosed()); - $this->assertTrue($payment->getShouldCloseParentTransaction()); - $this->assertEquals('1234', $payment->getTransactionAdditionalInfo()['real_transaction_id']); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php deleted file mode 100644 index a37f927274242..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/ConfigTest.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway; - -use Magento\Framework\Config\Data; -use Magento\Payment\Model\Method\Adapter; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; -use PHPUnit\Framework\TestCase; - -class ConfigTest extends TestCase -{ - /** - * @var ObjectManager - */ - private $objectManager; - - protected function setUp() - { - $this->objectManager = Bootstrap::getObjectManager(); - } - - public function testVerifyConfiguration() - { - /** @var Adapter $paymentAdapter */ - $paymentAdapter = $this->objectManager->get('AuthorizenetAcceptjsFacade'); - - $this->assertEquals('authorizenet_acceptjs', $paymentAdapter->getCode()); - $this->assertTrue($paymentAdapter->canAuthorize()); - $this->assertTrue($paymentAdapter->canCapture()); - $this->assertFalse($paymentAdapter->canCapturePartial()); - $this->assertTrue($paymentAdapter->canRefund()); - $this->assertTrue($paymentAdapter->canUseCheckout()); - $this->assertTrue($paymentAdapter->canVoid()); - $this->assertTrue($paymentAdapter->canUseInternal()); - $this->assertTrue($paymentAdapter->canEdit()); - $this->assertTrue($paymentAdapter->canFetchTransactionInfo()); - - /** @var Data $configReader */ - $configReader = $this->objectManager->get('Magento\Payment\Model\Config\Data'); - $value = $configReader->get('methods/authorizenet_acceptjs/allow_multiple_address'); - - $this->assertSame('0', $value); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseTransactionHandlerTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseTransactionHandlerTest.php deleted file mode 100644 index 1bee2e95cef7d..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Gateway/Response/CloseTransactionHandlerTest.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetAcceptjs\Gateway\Response; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; - -/** - * Test for Magento\AuthorizenetAcceptjs\Gateway\Response\CloseTransactionHandler class. - */ -class CloseTransactionHandlerTest extends AbstractTest -{ - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/AuthorizenetAcceptjs/Fixture/order_auth_only.php - * - * @return void - */ - public function testTransactionCloseStatus(): void - { - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('settle'); - $order = $this->getOrderWithIncrementId('100000002'); - $payment = $order->getPayment(); - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../_files/expected_request/settle.php'; - $response = include __DIR__ . '/../../_files/response/settle.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute(['payment' => $paymentDO]); - - $this->assertFalse($payment->getIsTransactionClosed()); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/accept_fds.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/accept_fds.php deleted file mode 100644 index d843de1c2cac0..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/accept_fds.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'updateHeldTransactionRequest' => [ - 'merchantAuthentication' => [ - 'name' => 'someusername', - 'transactionKey' => 'somepassword' - ], - 'heldTransactionRequest' => [ - 'action' => 'approve', - 'refTransId' => '1234', - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/authorize.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/authorize.php deleted file mode 100644 index 16debdb2ef820..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/authorize.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'authOnlyTransaction', - 'amount' => '100.00', - 'payment' => [ - 'opaqueData' => [ - 'dataDescriptor' => 'mydescriptor', - 'dataValue' => 'myvalue', - ], - ], - 'solution' => [ - 'id' => 'AAA102993', - ], - 'order' => [ - 'invoiceNumber' => '100000001', - ], - 'poNumber' => null, - 'customer' => [ - 'id' => 1, - 'email' => 'admin@example.com', - ], - 'billTo' => [ - 'firstName' => 'firstname', - 'lastName' => 'lastname', - 'company' => '', - 'address' => 'street', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'shipTo' => [ - 'firstName' => 'John', - 'lastName' => 'Doe', - 'company' => '', - 'address' => '6161 West Centinela Avenue', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'customerIP' => '127.0.0.1', - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction', - ], - ], - ], - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/refund.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/refund.php deleted file mode 100644 index 5ed331d076f66..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/refund.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'refundTransaction', - 'amount' => '100.00', - 'payment' => [ - 'creditCard' => [ - 'cardNumber' => '1111', - 'expirationDate' => 'XXXX' - ] - ], - 'refTransId' => '4321', - 'order' => [ - 'invoiceNumber' => '100000001', - ], - 'poNumber' => null, - 'customer' => [ - 'id' => '1', - 'email' => 'admin@example.com', - ], - 'billTo' => [ - 'firstName' => 'firstname', - 'lastName' => 'lastname', - 'company' => '', - 'address' => 'street', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'shipTo' => [ - 'firstName' => 'John', - 'lastName' => 'Doe', - 'company' => '', - 'address' => '6161 West Centinela Avenue', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'customerIP' => '127.0.0.1' - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/sale.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/sale.php deleted file mode 100644 index 4514acbcb6646..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/sale.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'authCaptureTransaction', - 'amount' => '100.00', - 'payment' => [ - 'opaqueData' => [ - 'dataDescriptor' => 'mydescriptor', - 'dataValue' => 'myvalue', - ], - ], - 'solution' => [ - 'id' => 'AAA102993', - ], - 'order' => [ - 'invoiceNumber' => '100000001', - ], - 'poNumber' => null, - 'customer' => [ - 'id' => 1, - 'email' => 'admin@example.com', - ], - 'billTo' => [ - 'firstName' => 'firstname', - 'lastName' => 'lastname', - 'company' => '', - 'address' => 'street', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'shipTo' => [ - 'firstName' => 'John', - 'lastName' => 'Doe', - 'company' => '', - 'address' => '6161 West Centinela Avenue', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'customerIP' => '127.0.0.1', - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'transactionType', - 'value' => 'authCaptureTransaction', - ], - ], - ], - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/settle.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/settle.php deleted file mode 100644 index b4fa88cc1e5a9..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/settle.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'priorAuthCaptureTransaction', - 'refTransId' => '1234', - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'transactionType', - 'value' => 'priorAuthCaptureTransaction', - ], - ], - ], - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/transaction_details.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/transaction_details.php deleted file mode 100644 index 110333866766e..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/transaction_details.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'getTransactionDetailsRequest' => [ - 'merchantAuthentication' => [ - 'name' => 'someusername', - 'transactionKey' => 'somepassword' - ], - 'transId' => '4321' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/transaction_details_authorized.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/transaction_details_authorized.php deleted file mode 100644 index c3ffdedba6851..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/transaction_details_authorized.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'getTransactionDetailsRequest' => [ - 'merchantAuthentication' => [ - 'name' => 'someusername', - 'transactionKey' => 'somepassword' - ], - 'transId' => '1234' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/void.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/void.php deleted file mode 100644 index a1d3dade74ff1..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/expected_request/void.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' => [ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' =>[ - 'transactionType' => 'voidTransaction', - 'refTransId' => '1234', - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/full_order.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/full_order.php deleted file mode 100644 index 420d0f55cf34e..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/full_order.php +++ /dev/null @@ -1,129 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Attribute\Source\Status; -use Magento\Catalog\Model\Product\Type; -use Magento\Catalog\Model\Product\Visibility; -use Magento\Sales\Model\Order; -use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\Order\Address; -use Magento\Sales\Model\Order\Item; -use Magento\TestFramework\Helper\Bootstrap; - -$addressData = include __DIR__ . '/../../../Magento/Sales/_files/address_data.php'; -require __DIR__ . '/../../../Magento/Customer/_files/customer.php'; - -$objectManager = Bootstrap::getObjectManager(); - -/** @var $product Product */ -$product = $objectManager->create(Product::class); -$product->isObjectNew(true); -$product->setTypeId(Type::TYPE_SIMPLE) - ->setId(1) - ->setAttributeSetId(4) - ->setWebsiteIds([1]) - ->setName('Simple Product') - ->setSku('simple') - ->setPrice(10) - ->setWeight(1) - ->setShortDescription('Short description') - ->setTaxClassId(0) - ->setDescription('Description with <b>html tag</b>') - ->setMetaTitle('meta title') - ->setMetaKeyword('meta keyword') - ->setMetaDescription('meta description') - ->setVisibility(Visibility::VISIBILITY_BOTH) - ->setStatus(Status::STATUS_ENABLED) - ->setStockData( - [ - 'use_config_manage_stock' => 1, - 'qty' => 100, - 'is_qty_decimal' => 0, - 'is_in_stock' => 1, - ] - )->setCanSaveCustomOptions(true) - ->setHasOptions(false); - -/** @var ProductRepositoryInterface $productRepository */ -$productRepository = $objectManager->create(ProductRepositoryInterface::class); -$productRepository->save($product); - - -$billingAddress = $objectManager->create(Address::class, ['data' => $addressData]); -$billingAddress->setAddressType('billing'); - -$shippingAddress = clone $billingAddress; -$shippingAddress->setId(null) - ->setAddressType('shipping') - ->setStreet(['6161 West Centinela Avenue']) - ->setFirstname('John') - ->setLastname('Doe') - ->setShippingMethod('flatrate_flatrate'); - -/** @var Payment $payment */ -$payment = $objectManager->create(Payment::class); -$payment->setAdditionalInformation('ccLast4', '1111'); -$payment->setAdditionalInformation('opaqueDataDescriptor', 'mydescriptor'); -$payment->setAdditionalInformation('opaqueDataValue', 'myvalue'); - -/** @var Item $orderItem */ -$orderItem1 = $objectManager->create(Item::class); -$orderItem1->setProductId($product->getId()) - ->setSku($product->getSku()) - ->setName($product->getName()) - ->setQtyOrdered(1) - ->setBasePrice($product->getPrice()) - ->setPrice($product->getPrice()) - ->setRowTotal($product->getPrice()) - ->setProductType($product->getTypeId()); - -/** @var Item $orderItem */ -$orderItem2 = $objectManager->create(Item::class); -$orderItem2->setProductId($product->getId()) - ->setSku('simple2') - ->setName('Simple product') - ->setPrice(100) - ->setQtyOrdered(2) - ->setBasePrice($product->getPrice()) - ->setPrice($product->getPrice()) - ->setRowTotal($product->getPrice()) - ->setProductType($product->getTypeId()); - -$orderAmount = 100; -$customerEmail = $billingAddress->getEmail(); - -/** @var Order $order */ -$order = $objectManager->create(Order::class); -$order->setIncrementId('100000001') - ->setState(Order::STATE_PROCESSING) - ->setStatus(Order::STATE_PROCESSING) - ->setCustomerId($customer->getId()) - ->setCustomerIsGuest(false) - ->setRemoteIp('127.0.0.1') - ->setCreatedAt(date('Y-m-d 00:00:55')) - ->setOrderCurrencyCode('USD') - ->setBaseCurrencyCode('USD') - ->setSubtotal($orderAmount) - ->setGrandTotal($orderAmount) - ->setBaseSubtotal($orderAmount) - ->setBaseGrandTotal($orderAmount) - ->setCustomerEmail($customerEmail) - ->setBillingAddress($billingAddress) - ->setShippingAddress($shippingAddress) - ->setShippingDescription('Flat Rate - Fixed') - ->setShippingAmount(10) - ->setBaseShippingAmount(10) - ->setStoreId(1) - ->addItem($orderItem1) - ->addItem($orderItem2) - ->setQuoteId(1) - ->setPayment($payment); - -return $order; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/authorize.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/authorize.php deleted file mode 100644 index f80495137ca29..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/authorize.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'transactionResponse' => [ - 'responseCode' => '1', - 'authCode' => 'abc123', - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '2', - 'transId' => '123456', - 'refTransID' => '', - 'transHash' => 'foobar', - 'testRequest' => '0', - 'accountNumber' => 'XXXX1111', - 'accountType' => 'Visa', - 'messages' => [ - [ - 'code' => '1', - 'description' => 'This transaction has been approved.' - ] - ], - 'userFields' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction' - ] - ], - 'transHashSha2' => 'CD1E57FB1B5C876FDBD536CB16F8BBBA687580EDD78DD881C7F14DC4467C32BF6C' - . '808620FBD59E5977DF19460B98CCFC0DA0D90755992C0D611CABB8E2BA52B0', - 'SupplementalDataQualificationIndicator' => 0 - ], - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'I00001', - 'text' => 'Successful.' - ] - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/generic_success.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/generic_success.php deleted file mode 100644 index ea7662e319376..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/generic_success.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - 'code' => 'I00001', - 'text' => 'Successful' - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/refund.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/refund.php deleted file mode 100644 index 536f51d659ad8..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/refund.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'transactionResponse' => [ - 'responseCode' => '1', - 'authCode' => '', - 'avsResultCode' => 'P', - 'cvvResultCode' => '', - 'cavvResultCode' => '', - 'transId' => '5678', - 'refTransID' => '4321', - 'testRequest' => '0', - 'accountNumber' => 'XXXX1111', - 'accountType' => 'Visa', - 'messages' => [ - [ - 'code' => '1', - 'description' => 'This transaction has been approved.' - ] - ], - 'transHashSha2' => '78BD31BA5BCDF3C3FA3C8373D8DF80EF07FC7E02C3545FCF18A408E2F76ED4F20D' - . 'FF007221374B576FDD1BFD953B3E5CF37249CEC4C135EEF975F7B478D8452C', - 'SupplementalDataQualificationIndicator' => 0 - ], - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'I00001', - 'text' => 'Successful.' - ] - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/sale.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/sale.php deleted file mode 100644 index 74a80110adece..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/sale.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'transactionResponse' => [ - 'responseCode' => '1', - 'authCode' => 'abc123', - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '2', - 'transId' => '123456', - 'refTransID' => '', - 'transHash' => 'foobar', - 'testRequest' => '0', - 'accountNumber' => 'XXXX1111', - 'accountType' => 'Visa', - 'messages' => [ - [ - 'code' => '1', - 'description' => 'This transaction has been approved.' - ] - ], - 'userFields' => [ - [ - 'name' => 'transactionType', - 'value' => 'authCaptureTransaction' - ] - ], - 'transHashSha2' => 'CD1E57FB1B5C876FDBD536CB16F8BBBA687580EDD78DD881C7F14DC4467C32BF6C' - . '808620FBD59E5977DF19460B98CCFC0DA0D90755992C0D611CABB8E2BA52B0', - 'SupplementalDataQualificationIndicator' => 0 - ], - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'I00001', - 'text' => 'Successful.' - ] - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/settle.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/settle.php deleted file mode 100644 index 5e54c30198741..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/settle.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'transactionResponse' => [ - 'responseCode' => '1', - 'authCode' => '', - 'avsResultCode' => 'P', - 'cvvResultCode' => '', - 'cavvResultCode' => '', - 'transId' => '1234', - 'refTransID' => '1234', - 'testRequest' => '0', - 'accountNumber' => 'XXXX1111', - 'accountType' => 'Visa', - 'messages' => [ - [ - 'code' => '1', - 'description' => 'This transaction has been approved.' - ] - ], - 'transHashSha2' => '1B22AB4E4DF750CF2E0D1944BB6903537C145545C7313C87B6FD4A6384' - . '709EA2609CE9A9788C128F2F2EAEEE474F6010418904648C6D000BE3AF7BCD98A5AD8F', - 'SupplementalDataQualificationIndicator' => 0 - ], - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'I00001', - 'text' => 'Successful.' - ] - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_authorized.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_authorized.php deleted file mode 100644 index 80fd24a5c601a..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_authorized.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - 'code' => 'I00001', - 'text' => 'Successful' - ] - ], - 'transaction' => [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction', - 'transactionStatus' => 'authorizedPendingCapture' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_declined.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_declined.php deleted file mode 100644 index 24c9353e4088a..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_declined.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - 'code' => 'I00001', - 'text' => 'Successful' - ] - ], - 'transaction' => [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction', - 'transactionStatus' => 'declined' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_fds_pending.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_fds_pending.php deleted file mode 100644 index de045f30ab22e..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_fds_pending.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - 'code' => 'I00001', - 'text' => 'Successful' - ] - ], - 'transaction' => [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction', - 'transactionStatus' => 'FDSPendingReview' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_settled_capture.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_settled_capture.php deleted file mode 100644 index 5df2f03a943a6..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_settled_capture.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - 'code' => 'I00001', - 'text' => 'Successful' - ] - ], - 'transaction' => [ - 'transId' => '4321', - 'transactionType' => 'captureOnlyTransaction', - 'transactionStatus' => 'settledSuccessfully' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_voided.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_voided.php deleted file mode 100644 index 7ee735cd8cf36..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/transaction_details_voided.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - 'code' => 'I00001', - 'text' => 'Successful' - ] - ], - 'transaction' => [ - 'transId' => '1234', - 'transactionType' => 'authOnlyTransaction', - 'transactionStatus' => 'void' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/void.php b/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/void.php deleted file mode 100644 index eb71de4dd9667..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/_files/response/void.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - 'code' => 'I00001', - 'text' => 'Successful' - ] - ], - 'transactionResponse' => [ - 'responseCode' => '1', - 'messages' => [ - 'message' => [ - [ - 'code' => 1 - ] - ] - ], - 'transHashSha2' => '1B22AB4E4DF750CF2E0D1944BB6903537C145545C7313C87B6FD4A6384709E' - . 'A2609CE9A9788C128F2F2EAEEE474F6010418904648C6D000BE3AF7BCD98A5AD8F', - 'transId' => '1234' - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/expected_request/authorize.php b/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/expected_request/authorize.php deleted file mode 100644 index ceab22403d987..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/expected_request/authorize.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'authOnlyTransaction', - 'amount' => '100.00', - 'payment' => [ - 'opaqueData' => [ - 'dataDescriptor' => 'mydescriptor', - 'dataValue' => 'myvalue', - ], - ], - 'solution' => [ - 'id' => 'AAA102993', - ], - 'order' => [ - 'invoiceNumber' => '100000001', - ], - 'poNumber' => null, - 'customer' => [ - 'id' => 1, - 'email' => 'admin@example.com', - ], - 'billTo' => [ - 'firstName' => 'firstname', - 'lastName' => 'lastname', - 'company' => '', - 'address' => 'street', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'shipTo' => [ - 'firstName' => 'John', - 'lastName' => 'Doe', - 'company' => '', - 'address' => '6161 West Centinela Avenue', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'customerIP' => '127.0.0.1', - 'cardholderAuthentication' => [ - 'authenticationIndicator' => '05', - 'cardholderAuthenticationValue' => 'AAABAWFlmQAAAABjRWWZEEFgFz8=', - ], - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction', - ], - ], - ], - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/expected_request/sale.php b/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/expected_request/sale.php deleted file mode 100644 index f96facb19b3b5..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/expected_request/sale.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'authCaptureTransaction', - 'amount' => '100.00', - 'payment' => [ - 'opaqueData' => [ - 'dataDescriptor' => 'mydescriptor', - 'dataValue' => 'myvalue', - ], - ], - 'solution' => [ - 'id' => 'AAA102993', - ], - 'order' => [ - 'invoiceNumber' => '100000001', - ], - 'poNumber' => null, - 'customer' => [ - 'id' => 1, - 'email' => 'admin@example.com', - ], - 'billTo' => [ - 'firstName' => 'firstname', - 'lastName' => 'lastname', - 'company' => '', - 'address' => 'street', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'shipTo' => [ - 'firstName' => 'John', - 'lastName' => 'Doe', - 'company' => '', - 'address' => '6161 West Centinela Avenue', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'customerIP' => '127.0.0.1', - 'cardholderAuthentication' => [ - 'authenticationIndicator' => '05', - 'cardholderAuthenticationValue' => 'AAABAWFlmQAAAABjRWWZEEFgFz8=', - ], - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'transactionType', - 'value' => 'authCaptureTransaction', - ], - ], - ], - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/full_order_with_3dsecure.php b/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/full_order_with_3dsecure.php deleted file mode 100644 index 4f50b502e8554..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/full_order_with_3dsecure.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -use Magento\Sales\Model\Order\Payment; -use Magento\TestFramework\Helper\Bootstrap; - -$order = include __DIR__ . '/../../AuthorizenetAcceptjs/_files/full_order.php'; - -$objectManager = Bootstrap::getObjectManager(); -$cardinalJWT = include __DIR__ . '/response/cardinal_jwt.php'; - -/** @var Payment $payment */ -$payment = $order->getPayment(); -$payment->setAdditionalInformation('cardinalJWT', $cardinalJWT); - -return $order; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/response/authorize.php b/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/response/authorize.php deleted file mode 100644 index c17b14721b157..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/response/authorize.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'transactionResponse' => [ - 'responseCode' => '1', - 'authCode' => 'abc123', - 'avsResultCode' => 'P', - 'cvvResultCode' => '', - 'cavvResultCode' => '2', - 'transId' => '123456', - 'refTransID' => '', - 'transHash' => 'foobar', - 'testRequest' => '0', - 'accountNumber' => 'XXXX1111', - 'accountType' => 'Visa', - 'messages' => [ - [ - 'code' => '1', - 'description' => 'This transaction has been approved.' - ] - ], - 'userFields' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction' - ] - ], - 'transHashSha2' => 'CD1E57FB1B5C876FDBD536CB16F8BBBA687580EDD78DD881C7F14DC4467C32BF6C' - . '808620FBD59E5977DF19460B98CCFC0DA0D90755992C0D611CABB8E2BA52B0', - 'SupplementalDataQualificationIndicator' => 0 - ], - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'I00001', - 'text' => 'Successful.' - ] - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/response/cardinal_jwt.php b/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/response/cardinal_jwt.php deleted file mode 100644 index 80f42524897f6..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Fixture/response/cardinal_jwt.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -use Magento\CardinalCommerce\Model\Config; -use Magento\CardinalCommerce\Model\JwtManagement; -use Magento\TestFramework\Helper\Bootstrap; - -$objectManager = Bootstrap::getObjectManager(); -/** @var JwtManagement $jwtManagment */ -$jwtManagment = $objectManager->get(JwtManagement::class); -/** @var Config $config */ -$config = $objectManager->get(Config::class); -$currentDate = new \DateTime('now', new \DateTimeZone('UTC')); -$response = [ - 'iss' => 'some_api_identifier', - 'iat' => 1559855656, - 'exp' => $currentDate->getTimestamp() + 3600, - 'jti' => '0d695df5-ca06-4f7d-b150-ff169510f6d2', - 'ConsumerSessionId' => '0_9e6a4084-2191-4fd7-9631-19f576375e0a', - 'ReferenceId' => '0_9e6a4084-2191-4fd7-9631-19f576375e0a', - 'aud' => '52efb9cc-843c-4ee9-a38c-107943be6b03', - 'Payload' => [ - 'Validated' => true, - 'Payment' => [ - 'Type' => 'CCA', - 'ProcessorTransactionId' => '4l7xg1WA7CS0YwgPgNZ0', - 'ExtendedData' => [ - 'CAVV' => 'AAABAWFlmQAAAABjRWWZEEFgFz8=', - 'ECIFlag' => '05', - 'XID' => 'NGw3eGcxV0E3Q1MwWXdnUGdOWjA=', - 'Enrolled' => 'Y', - 'PAResStatus' => 'Y', - 'SignatureVerification' => 'Y', - ], - ], - 'ActionCode' => 'SUCCESS', - 'ErrorNumber' => 0, - 'ErrorDescription' => 'Success', - ], -]; -$cardinalJWT = $jwtManagment->encode($response, $config->getApiKey()); - -return $cardinalJWT; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Gateway/Command/AuthorizeCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Gateway/Command/AuthorizeCommandTest.php deleted file mode 100644 index 561734b089213..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Gateway/Command/AuthorizeCommandTest.php +++ /dev/null @@ -1,187 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetCardinal\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Framework\Exception\LocalizedException; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\Order\Payment\Transaction; - -/** - * Tests "Authorize" command for Authorize.net payment requests with 3D-Secure. - */ -class AuthorizeCommandTest extends AbstractTest -{ - /** - * Tests Authorize command with enabled 3D secure and valid Cardinal response JWT. - * - * @magentoConfigFixture default_store three_d_secure/cardinal/enabled_authorizenet 1 - * @magentoConfigFixture default_store three_d_secure/cardinal/environment sandbox - * @magentoConfigFixture default_store three_d_secure/cardinal/api_key some_api_key - * @magentoConfigFixture default_store three_d_secure/cardinal/api_identifier some_api_identifier - * @magentoConfigFixture default_store three_d_secure/cardinal/org_unit_id some_org_unit_id - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * - * @magentoAppIsolation enabled - */ - public function testAuthorizeCommandWith3dSecure() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('authorize'); - - $order = include __DIR__ . '/../../Fixture/full_order_with_3dsecure.php'; - $payment = $order->getPayment(); - - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../Fixture/expected_request/authorize.php'; - $response = include __DIR__ . '/../../Fixture/response/authorize.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute( - [ - 'payment' => $paymentDO, - 'amount' => 100.00 - ] - ); - - /** @var Payment $payment */ - $rawDetails = [ - 'authCode' => 'abc123', - 'avsResultCode' => 'P', - 'cvvResultCode' => '', - 'cavvResultCode' => '2', - 'accountType' => 'Visa', - ]; - $this->assertSame('1111', $payment->getCcLast4()); - $this->assertSame('P', $payment->getCcAvsStatus()); - $this->assertFalse($payment->getData('is_transaction_closed')); - - $transactionDetails = $payment->getTransactionAdditionalInfo(); - foreach ($rawDetails as $key => $value) { - $this->assertSame($value, $payment->getAdditionalInformation($key)); - $this->assertSame($value, $transactionDetails[Transaction::RAW_DETAILS][$key]); - } - - $this->assertSame('123456', $payment->getTransactionId()); - $this->assertSame('123456', $transactionDetails['real_transaction_id']); - } - - /** - * Tests Authorize command with enabled 3D secure and invalid Cardinal response JWT. - * - * @magentoConfigFixture default_store three_d_secure/cardinal/enabled_authorizenet 1 - * @magentoConfigFixture default_store three_d_secure/cardinal/environment sandbox - * @magentoConfigFixture default_store three_d_secure/cardinal/api_key some_api_key - * @magentoConfigFixture default_store three_d_secure/cardinal/api_identifier some_api_identifier - * @magentoConfigFixture default_store three_d_secure/cardinal/org_unit_id some_org_unit_id - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * - * @magentoAppIsolation enabled - */ - public function testAuthorizeCommandWithInvalidJwt() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('authorize'); - - $order = include __DIR__ . '/../../../AuthorizenetAcceptjs/_files/full_order.php'; - $payment = $order->getPayment(); - $payment->setAdditionalInformation('cardinalJWT', 'Invalid JWT'); - - $paymentDO = $this->paymentFactory->create($payment); - - $this->expectException(LocalizedException::class); - - $command->execute( - [ - 'payment' => $paymentDO, - 'amount' => 100.00 - ] - ); - } - - /** - * Tests Authorize command with disabled 3D secure. - * - * @magentoConfigFixture default_store three_d_secure/cardinal/enabled_authorizenet 0 - * @magentoConfigFixture default_store three_d_secure/cardinal/environment sandbox - * @magentoConfigFixture default_store three_d_secure/cardinal/api_key some_api_key - * @magentoConfigFixture default_store three_d_secure/cardinal/api_identifier some_api_identifier - * @magentoConfigFixture default_store three_d_secure/cardinal/org_unit_id some_org_unit_id - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * - * @magentoAppIsolation enabled - */ - public function testAuthorizeCommandWithDisabled3dSecure() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('authorize'); - - $order = include __DIR__ . '/../../Fixture/full_order_with_3dsecure.php'; - $payment = $order->getPayment(); - - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../../AuthorizenetAcceptjs/_files/expected_request/authorize.php'; - $response = include __DIR__ . '/../../../AuthorizenetAcceptjs/_files/response/authorize.php'; - $response['transactionResponse']['cavvResultCode'] = '0'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute( - [ - 'payment' => $paymentDO, - 'amount' => 100.00 - ] - ); - - /** @var Payment $payment */ - $rawDetails = [ - 'authCode' => 'abc123', - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '0', - 'accountType' => 'Visa', - ]; - $this->assertSame('1111', $payment->getCcLast4()); - $this->assertSame('Y', $payment->getCcAvsStatus()); - $this->assertFalse($payment->getData('is_transaction_closed')); - - $transactionDetails = $payment->getTransactionAdditionalInfo(); - foreach ($rawDetails as $key => $value) { - $this->assertSame($value, $payment->getAdditionalInformation($key)); - $this->assertSame($value, $transactionDetails[Transaction::RAW_DETAILS][$key]); - } - - $this->assertSame('123456', $payment->getTransactionId()); - $this->assertSame('123456', $transactionDetails['real_transaction_id']); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Gateway/Command/SaleCommandTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Gateway/Command/SaleCommandTest.php deleted file mode 100644 index c22e1fceaa84f..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetCardinal/Gateway/Command/SaleCommandTest.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\AuthorizenetCardinal\Gateway\Command; - -use Magento\AuthorizenetAcceptjs\Gateway\AbstractTest; -use Magento\Framework\Exception\LocalizedException; -use Magento\Payment\Gateway\Command\CommandPoolInterface; -use Magento\Sales\Model\Order\Payment; -use Magento\Sales\Model\Order\Payment\Transaction; - -/** - * Tests "Sale" command for Authorize.net payment requests with 3D-Secure. - */ -class SaleCommandTest extends AbstractTest -{ - /** - * Tests Sale command with enabled 3D secure and valid Cardinal response JWT. - * - * @magentoConfigFixture default_store three_d_secure/cardinal/enabled_authorizenet 1 - * @magentoConfigFixture default_store three_d_secure/cardinal/environment sandbox - * @magentoConfigFixture default_store three_d_secure/cardinal/api_key some_api_key - * @magentoConfigFixture default_store three_d_secure/cardinal/api_identifier some_api_identifier - * @magentoConfigFixture default_store three_d_secure/cardinal/org_unit_id some_org_unit_id - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * - * @magentoAppIsolation enabled - */ - public function testSaleCommandWith3dSecure() - { - /** @var CommandPoolInterface $commandPool */ - $commandPool = $this->objectManager->get('AuthorizenetAcceptjsCommandPool'); - $command = $commandPool->get('sale'); - - $order = include __DIR__ . '/../../Fixture/full_order_with_3dsecure.php'; - $payment = $order->getPayment(); - - $paymentDO = $this->paymentFactory->create($payment); - - $expectedRequest = include __DIR__ . '/../../Fixture/expected_request/sale.php'; - $response = include __DIR__ . '/../../../AuthorizenetAcceptjs/_files/response/sale.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody') - ->willReturn(json_encode($response)); - - $command->execute( - [ - 'payment' => $paymentDO, - 'amount' => 100.00 - ] - ); - - /** @var Payment $payment */ - $rawDetails = [ - 'authCode' => 'abc123', - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '2', - 'accountType' => 'Visa', - ]; - $this->assertSame('1111', $payment->getCcLast4()); - $this->assertSame('Y', $payment->getCcAvsStatus()); - $this->assertFalse($payment->getData('is_transaction_closed')); - - $transactionDetails = $payment->getTransactionAdditionalInfo(); - foreach ($rawDetails as $key => $value) { - $this->assertSame($value, $payment->getAdditionalInformation($key)); - $this->assertSame($value, $transactionDetails[Transaction::RAW_DETAILS][$key]); - } - - $this->assertSame('123456', $payment->getTransactionId()); - $this->assertSame('123456', $transactionDetails['real_transaction_id']); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php deleted file mode 100644 index fa3869d49bd2a..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php +++ /dev/null @@ -1,158 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\AuthorizenetGraphQl\Model\Resolver\Customer; - -use Magento\Framework\Serialize\SerializerInterface; -use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; -use Magento\GraphQl\Service\GraphQlRequest; -use Magento\Integration\Api\CustomerTokenServiceInterface; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\HTTP\ZendClient; -use Magento\Framework\HTTP\ZendClientFactory; -use Magento\TestFramework\ObjectManager; -use PHPUnit\Framework\MockObject\Builder\InvocationMocker; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; -use Zend_Http_Response; - -/** - * Tests end to end Place Order process for customer via authorizeNet - * - * @magentoAppArea graphql - * @magentoDbIsolation disabled - */ -class PlaceOrderWithAuthorizeNetTest extends TestCase -{ - /** @var ObjectManager */ - private $objectManager; - - /** @var GetMaskedQuoteIdByReservedOrderId */ - private $getMaskedQuoteIdByReservedOrderId; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var GraphQlRequest */ - private $graphQlRequest; - - /** @var ZendClient|MockObject|InvocationMocker */ - private $clientMock; - - /** @var CustomerTokenServiceInterface */ - private $customerTokenService; - - /** @var Zend_Http_Response */ - protected $responseMock; - - protected function setUp() : void - { - $this->objectManager = Bootstrap::getObjectManager(); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->graphQlRequest = $this->objectManager->create(GraphQlRequest::class); - $this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); - $this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class); - $this->clientMock = $this->createMock(ZendClient::class); - $this->responseMock = $this->createMock(Zend_Http_Response::class); - $this->clientMock->method('request') - ->willReturn($this->responseMock); - $this->clientMock->method('setUri') - ->with('https://apitest.authorize.net/xml/v1/request.api'); - $clientFactoryMock = $this->createMock(ZendClientFactory::class); - $clientFactoryMock->method('create') - ->willReturn($this->clientMock); - $this->objectManager->addSharedInstance($clientFactoryMock, ZendClientFactory::class); - } - - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/Sales/_files/default_rollback.php - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/set_new_shipping_address_authorizenet.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/set_new_billing_address_authorizenet.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/add_simple_products_authorizenet.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php - */ - public function testDispatchToPlaceOrderWithRegisteredCustomer(): void - { - $paymentMethod = 'authorizenet_acceptjs'; - $cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - $query - = <<<QUERY - mutation { - setPaymentMethodOnCart(input: { - cart_id: "$cartId" - payment_method: { - code: "$paymentMethod" - authorizenet_acceptjs: - {opaque_data_descriptor: "mydescriptor", - opaque_data_value: "myvalue", - cc_last_4: 1111} - } - }) { - cart { - selected_payment_method { - code - } - } - } - placeOrder(input: {cart_id: "$cartId"}) { - order { - order_number - } - } -} -QUERY; - - $customerToken = $this->customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); - $requestHeaders = [ - 'Accept' => 'application/json', - 'Authorization' => 'Bearer ' . $customerToken - ]; - // phpcs:ignore Magento2.Security.IncludeFile - $expectedRequest = include __DIR__ . '/../../../_files/request_authorize_customer.php'; - // phpcs:ignore Magento2.Security.IncludeFile - $authorizeResponse = include __DIR__ . '/../../../_files/response_authorize.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody')->willReturn(json_encode($authorizeResponse)); - - $response = $this->graphQlRequest->send($query, [], '', $requestHeaders); - $responseData = $this->jsonSerializer->unserialize($response->getContent()); - - $this->assertArrayNotHasKey('errors', $responseData, 'Response has errors'); - $this->assertTrue( - isset($responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']) - ); - $this->assertEquals( - $paymentMethod, - $responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code'] - ); - - $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_number']) - ); - - $this->assertEquals( - 'test_quote', - $responseData['data']['placeOrder']['order']['order_number'] - ); - } - - protected function tearDown() - { - $this->objectManager->removeSharedInstance(ZendClientFactory::class); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/SetAuthorizeNetPaymentMethodOnCartTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/SetAuthorizeNetPaymentMethodOnCartTest.php deleted file mode 100644 index b82469c61d288..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/SetAuthorizeNetPaymentMethodOnCartTest.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\AuthorizenetGraphQl\Model\Resolver\Customer; - -use Magento\Framework\Serialize\SerializerInterface; -use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; -use Magento\GraphQl\Service\GraphQlRequest; -use Magento\Integration\Api\CustomerTokenServiceInterface; -use Magento\TestFramework\Helper\Bootstrap; -use PHPUnit\Framework\TestCase; - -/** - * Tests SetPaymentMethod mutation for customer via authorizeNet payment - * - * @magentoAppArea graphql - * @magentoDbIsolation disabled - */ -class SetAuthorizeNetPaymentMethodOnCartTest extends TestCase -{ - /** @var \Magento\Framework\ObjectManagerInterface */ - private $objectManager; - - /** @var GetMaskedQuoteIdByReservedOrderId */ - private $getMaskedQuoteIdByReservedOrderId; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var CustomerTokenServiceInterface */ - private $customerTokenService; - - /** @var GraphQlRequest */ - private $graphQlRequest; - - protected function setUp() : void - { - $this->objectManager = Bootstrap::getObjectManager(); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->graphQlRequest = $this->objectManager->create(GraphQlRequest::class); - $this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); - $this->customerTokenService = $this->objectManager->get(CustomerTokenServiceInterface::class); - } - - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - */ - public function testDispatchToSetPaymentMethodWithAuthorizenet(): void - { - $methodCode = 'authorizenet_acceptjs'; - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - $query - = <<<QUERY - mutation { - setPaymentMethodOnCart(input: { - cart_id: "$maskedQuoteId" - payment_method: { - code: "$methodCode" - authorizenet_acceptjs: - {opaque_data_descriptor: "COMMON.ACCEPT.INAPP.PAYMENT", - opaque_data_value: "abx", - cc_last_4: 1111} - } - }) { - cart { - selected_payment_method { - code - } - } - } -} -QUERY; - - $customerToken = $this->customerTokenService->createCustomerAccessToken('customer@example.com', 'password'); - - $requestHeaders = [ - 'Accept' => 'application/json', - 'Authorization' => 'Bearer ' . $customerToken - ]; - - $response = $this->graphQlRequest->send($query, [], '', $requestHeaders); - - $output = $this->jsonSerializer->unserialize($response->getContent()); - $this->assertArrayNotHasKey('errors', $output, 'Response has errors'); - $this->assertArrayHasKey('setPaymentMethodOnCart', $output['data']); - $selectedPaymentMethod = $output['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']; - $this->assertEquals($methodCode, $selectedPaymentMethod['code']); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php deleted file mode 100644 index 4946448f91ccc..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\AuthorizenetGraphQl\Model\Resolver\Guest; - -use Magento\Framework\Serialize\SerializerInterface; -use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; -use Magento\GraphQl\Service\GraphQlRequest; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\HTTP\ZendClient; -use Magento\Framework\HTTP\ZendClientFactory; -use Magento\TestFramework\ObjectManager; -use PHPUnit\Framework\MockObject\Builder\InvocationMocker; -use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; -use Zend_Http_Response; - -/** - * Tests end to end Place Order process for non logged in customer using authorizeNet payment - * - * @magentoAppArea graphql - * @magentoDbIsolation disabled - */ -class PlaceOrderWithAuthorizeNetTest extends TestCase -{ - /** @var ObjectManager */ - private $objectManager; - - /** @var GetMaskedQuoteIdByReservedOrderId */ - private $getMaskedQuoteIdByReservedOrderId; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var GraphQlRequest */ - private $graphQlRequest; - - /** @var ZendClient|MockObject|InvocationMocker */ - private $clientMock; - - /** @var Zend_Http_Response */ - protected $responseMock; - - protected function setUp() : void - { - $this->objectManager = Bootstrap::getObjectManager(); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); - $this->graphQlRequest = $this->objectManager->create(GraphQlRequest::class); - $this->clientMock = $this->createMock(ZendClient::class); - $this->responseMock = $this->createMock(Zend_Http_Response::class); - $this->clientMock->method('request') - ->willReturn($this->responseMock); - $this->clientMock->method('setUri') - ->with('https://apitest.authorize.net/xml/v1/request.api'); - $clientFactoryMock = $this->createMock(ZendClientFactory::class); - $clientFactoryMock->method('create') - ->willReturn($this->clientMock); - $this->objectManager->addSharedInstance($clientFactoryMock, ZendClientFactory::class); - } - - protected function tearDown() - { - $this->objectManager->removeSharedInstance(ZendClientFactory::class); - } - - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/Sales/_files/default_rollback.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/guest/set_guest_email.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/set_new_shipping_address_authorizenet.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/set_new_billing_address_authorizenet.php - * @magentoDataFixture Magento/AuthorizenetGraphQl/_files/add_simple_products_authorizenet.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php - */ - public function testDispatchToPlaceAnOrderWithAuthorizenet(): void - { - $paymentMethod = 'authorizenet_acceptjs'; - $cartId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - $query - = <<<QUERY - mutation { - setPaymentMethodOnCart(input: { - cart_id: "$cartId" - payment_method: { - code: "$paymentMethod" - authorizenet_acceptjs: - {opaque_data_descriptor: "mydescriptor", - opaque_data_value: "myvalue", - cc_last_4: 1111} - } - }) { - cart { - selected_payment_method { - code - } - } - } - placeOrder(input: {cart_id: "$cartId"}) { - order { - order_number - } - } -} -QUERY; - - // phpcs:ignore Magento2.Security.IncludeFile - $expectedRequest = include __DIR__ . '/../../../_files/request_authorize.php'; - // phpcs:ignore Magento2.Security.IncludeFile - $authorizeResponse = include __DIR__ . '/../../../_files/response_authorize.php'; - - $this->clientMock->method('setRawData') - ->with(json_encode($expectedRequest), 'application/json'); - - $this->responseMock->method('getBody')->willReturn(json_encode($authorizeResponse)); - - $response = $this->graphQlRequest->send($query); - $responseData = $this->jsonSerializer->unserialize($response->getContent()); - - $this->assertArrayNotHasKey('errors', $responseData, 'Response has errors'); - $this->assertTrue( - isset($responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']) - ); - $this->assertEquals( - $paymentMethod, - $responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code'] - ); - - $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_number']) - ); - - $this->assertEquals( - 'test_quote', - $responseData['data']['placeOrder']['order']['order_number'] - ); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/SetAuthorizeNetPaymentMethodOnCartTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/SetAuthorizeNetPaymentMethodOnCartTest.php deleted file mode 100644 index ff526a491b5d7..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/SetAuthorizeNetPaymentMethodOnCartTest.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\AuthorizenetGraphQl\Model\Resolver\Guest; - -use Magento\Framework\Serialize\SerializerInterface; -use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; -use Magento\GraphQl\Service\GraphQlRequest; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\TestFramework\ObjectManager; -use PHPUnit\Framework\TestCase; - -/** - * Tests SetPaymentMethod mutation for guest via authorizeNet payment - * - * @magentoAppArea graphql - * @magentoDbIsolation disabled - */ -class SetAuthorizeNetPaymentMethodOnCartTest extends TestCase -{ - /** @var ObjectManager */ - private $objectManager; - - /** @var GetMaskedQuoteIdByReservedOrderId */ - private $getMaskedQuoteIdByReservedOrderId; - - /** @var SerializerInterface */ - private $jsonSerializer; - - /** @var GraphQlRequest */ - private $graphQlRequest; - - protected function setUp() : void - { - $this->objectManager = Bootstrap::getObjectManager(); - $this->jsonSerializer = $this->objectManager->get(SerializerInterface::class); - $this->getMaskedQuoteIdByReservedOrderId = $this->objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); - $this->graphQlRequest = $this->objectManager->create(GraphQlRequest::class); - } - - /** - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/environment sandbox - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/login someusername - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_key somepassword - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/trans_signature_key abc - * @magentoDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - * @magentoDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php - */ - public function testDispatchToSetPaymentMethodWithAuthorizenet(): void - { - $methodCode = 'authorizenet_acceptjs'; - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - $query - = <<<QUERY - mutation { - setPaymentMethodOnCart(input: { - cart_id: "$maskedQuoteId" - payment_method: { - code: "$methodCode" - authorizenet_acceptjs: - {opaque_data_descriptor: "COMMON.ACCEPT.INAPP.PAYMENT", - opaque_data_value: "abx", - cc_last_4: 1111} - } - }) { - cart { - selected_payment_method { - code - } - } - } -} -QUERY; - - $response = $this->graphQlRequest->send($query); - $output = $this->jsonSerializer->unserialize($response->getContent()); - $this->assertArrayNotHasKey('errors', $output, 'Response has errors'); - $this->assertArrayHasKey('setPaymentMethodOnCart', $output['data']); - $selectedPaymentMethod = $output['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']; - $this->assertEquals($methodCode, $selectedPaymentMethod['code']); - } -} diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/add_simple_products_authorizenet.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/add_simple_products_authorizenet.php deleted file mode 100644 index 3646e864ab49e..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/add_simple_products_authorizenet.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Quote\Model\QuoteFactory; -use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; -use Magento\TestFramework\Helper\Bootstrap; - -/** @var ProductRepositoryInterface $productRepository */ -$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); -/** @var QuoteFactory $quoteFactory */ -$quoteFactory = Bootstrap::getObjectManager()->get(QuoteFactory::class); -/** @var QuoteResource $quoteResource */ -$quoteResource = Bootstrap::getObjectManager()->get(QuoteResource::class); -/** @var CartRepositoryInterface $cartRepository */ -$cartRepository = Bootstrap::getObjectManager()->get(CartRepositoryInterface::class); - -$product = $productRepository->get('simple_product'); - -$quote = $quoteFactory->create(); -$quoteResource->load($quote, 'test_quote', 'reserved_order_id'); -$quote->addProduct($product, 4); -$cartRepository->save($quote); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/request_authorize.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/request_authorize.php deleted file mode 100644 index c91c8081736c4..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/request_authorize.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'authOnlyTransaction', - 'amount' => '100.00', - 'payment' => [ - 'opaqueData' => [ - 'dataDescriptor' => 'mydescriptor', - 'dataValue' => 'myvalue', - ], - ], - 'solution' => [ - 'id' => 'AAA102993', - ], - 'order' => [ - 'invoiceNumber' => 'test_quote', - ], - 'poNumber' => null, - 'customer' => [ - 'id' => null, - 'email' => 'guest@example.com', - ], - 'billTo' => [ - 'firstName' => 'firstname', - 'lastName' => 'lastname', - 'company' => '', - 'address' => 'street', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'shipTo' => [ - 'firstName' => 'John', - 'lastName' => 'Doe', - 'company' => '', - 'address' => '6161 West Centinela Avenue', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction', - ], - ], - ], - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/request_authorize_customer.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/request_authorize_customer.php deleted file mode 100644 index 0ef173009bd6c..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/request_authorize_customer.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'createTransactionRequest' => [ - 'merchantAuthentication' =>[ - 'name' => 'someusername', - 'transactionKey' => 'somepassword', - ], - 'transactionRequest' => [ - 'transactionType' => 'authOnlyTransaction', - 'amount' => '100.00', - 'payment' => [ - 'opaqueData' => [ - 'dataDescriptor' => 'mydescriptor', - 'dataValue' => 'myvalue', - ], - ], - 'solution' => [ - 'id' => 'AAA102993', - ], - 'order' => [ - 'invoiceNumber' => 'test_quote', - ], - 'poNumber' => null, - 'customer' => [ - 'id' => '1', - 'email' => 'customer@example.com', - ], - 'billTo' => [ - 'firstName' => 'firstname', - 'lastName' => 'lastname', - 'company' => '', - 'address' => 'street', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'shipTo' => [ - 'firstName' => 'John', - 'lastName' => 'Doe', - 'company' => '', - 'address' => '6161 West Centinela Avenue', - 'city' => 'Los Angeles', - 'state' => 'CA', - 'zip' => '11111', - 'country' => 'US', - ], - 'userFields' => [ - 'userField' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction', - ], - ], - ], - ], - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/response_authorize.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/response_authorize.php deleted file mode 100644 index f80495137ca29..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/response_authorize.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -return [ - 'transactionResponse' => [ - 'responseCode' => '1', - 'authCode' => 'abc123', - 'avsResultCode' => 'Y', - 'cvvResultCode' => 'P', - 'cavvResultCode' => '2', - 'transId' => '123456', - 'refTransID' => '', - 'transHash' => 'foobar', - 'testRequest' => '0', - 'accountNumber' => 'XXXX1111', - 'accountType' => 'Visa', - 'messages' => [ - [ - 'code' => '1', - 'description' => 'This transaction has been approved.' - ] - ], - 'userFields' => [ - [ - 'name' => 'transactionType', - 'value' => 'authOnlyTransaction' - ] - ], - 'transHashSha2' => 'CD1E57FB1B5C876FDBD536CB16F8BBBA687580EDD78DD881C7F14DC4467C32BF6C' - . '808620FBD59E5977DF19460B98CCFC0DA0D90755992C0D611CABB8E2BA52B0', - 'SupplementalDataQualificationIndicator' => 0 - ], - 'messages' => [ - 'resultCode' => 'Ok', - 'message' => [ - [ - 'code' => 'I00001', - 'text' => 'Successful.' - ] - ] - ] -]; diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/set_new_billing_address_authorizenet.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/set_new_billing_address_authorizenet.php deleted file mode 100644 index 4f045c550cd37..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/set_new_billing_address_authorizenet.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Framework\Api\DataObjectHelper; -use Magento\Quote\Api\Data\AddressInterface; -use Magento\Quote\Api\Data\AddressInterfaceFactory; -use Magento\Quote\Api\BillingAddressManagementInterface; -use Magento\Quote\Model\QuoteFactory; -use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; - -use Magento\TestFramework\Helper\Bootstrap; - -/** @var QuoteFactory $quoteFactory */ -$quoteFactory = Bootstrap::getObjectManager()->get(QuoteFactory::class); -/** @var QuoteResource $quoteResource */ -$quoteResource = Bootstrap::getObjectManager()->get(QuoteResource::class); -/** @var AddressInterfaceFactory $quoteAddressFactory */ -$quoteAddressFactory = Bootstrap::getObjectManager()->get(AddressInterfaceFactory::class); -/** @var DataObjectHelper $dataObjectHelper */ -$dataObjectHelper = Bootstrap::getObjectManager()->get(DataObjectHelper::class); -/** @var BillingAddressManagementInterface $billingAddressManagement */ -$billingAddressManagement = Bootstrap::getObjectManager()->get(BillingAddressManagementInterface::class); - -$quoteAddressData = [ - AddressInterface::KEY_TELEPHONE => 11111111, - AddressInterface::KEY_POSTCODE => 11111, - AddressInterface::KEY_COUNTRY_ID => 'US', - AddressInterface::KEY_CITY => 'Los Angeles', - AddressInterface::KEY_COMPANY => '', - AddressInterface::KEY_STREET => 'street', - AddressInterface::KEY_LASTNAME => 'lastname', - AddressInterface::KEY_FIRSTNAME => 'firstname', - AddressInterface::KEY_REGION_ID => 12, -]; -$quoteAddress = $quoteAddressFactory->create(); -$dataObjectHelper->populateWithArray($quoteAddress, $quoteAddressData, AddressInterfaceFactory::class); - -$quote = $quoteFactory->create(); -$quoteResource->load($quote, 'test_quote', 'reserved_order_id'); -$billingAddressManagement->assign($quote->getId(), $quoteAddress); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/set_new_shipping_address_authorizenet.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/set_new_shipping_address_authorizenet.php deleted file mode 100644 index 8837a3cb2397c..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/set_new_shipping_address_authorizenet.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Framework\Api\DataObjectHelper; -use Magento\Quote\Api\Data\AddressInterface; -use Magento\Quote\Api\Data\AddressInterfaceFactory; -use Magento\Quote\Model\QuoteFactory; -use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; -use Magento\Quote\Model\ShippingAddressManagementInterface; -use Magento\TestFramework\Helper\Bootstrap; - -/** @var QuoteFactory $quoteFactory */ -$quoteFactory = Bootstrap::getObjectManager()->get(QuoteFactory::class); -/** @var QuoteResource $quoteResource */ -$quoteResource = Bootstrap::getObjectManager()->get(QuoteResource::class); -/** @var AddressInterfaceFactory $quoteAddressFactory */ -$quoteAddressFactory = Bootstrap::getObjectManager()->get(AddressInterfaceFactory::class); -/** @var DataObjectHelper $dataObjectHelper */ -$dataObjectHelper = Bootstrap::getObjectManager()->get(DataObjectHelper::class); -/** @var ShippingAddressManagementInterface $shippingAddressManagement */ -$shippingAddressManagement = Bootstrap::getObjectManager()->get(ShippingAddressManagementInterface::class); - -$quoteAddressData = [ - AddressInterface::KEY_TELEPHONE => 3468676, - AddressInterface::KEY_POSTCODE => '11111', - AddressInterface::KEY_COUNTRY_ID => 'US', - AddressInterface::KEY_CITY => 'Los Angeles', - AddressInterface::KEY_COMPANY => '', - AddressInterface::KEY_STREET => '6161 West Centinela Avenue', - AddressInterface::KEY_LASTNAME => 'Doe', - AddressInterface::KEY_FIRSTNAME => 'John', - AddressInterface::KEY_REGION_ID => 12, -]; -$quoteAddress = $quoteAddressFactory->create(); -$dataObjectHelper->populateWithArray($quoteAddress, $quoteAddressData, AddressInterfaceFactory::class); - -$quote = $quoteFactory->create(); -$quoteResource->load($quote, 'test_quote', 'reserved_order_id'); -$shippingAddressManagement->assign($quote->getId(), $quoteAddress); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet.php deleted file mode 100644 index 50ec950853711..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Api\Data\ProductInterfaceFactory; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Catalog\Model\Product\Attribute\Source\Status; -use Magento\Catalog\Model\Product\Type; -use Magento\Catalog\Model\Product\Visibility; -use Magento\Framework\Api\DataObjectHelper; -use Magento\TestFramework\Helper\Bootstrap; - -$objectManager = Bootstrap::getObjectManager(); -/** @var ProductInterfaceFactory $productFactory */ -$productFactory = $objectManager->get(ProductInterfaceFactory::class); -/** @var DataObjectHelper $dataObjectHelper */ -$dataObjectHelper = Bootstrap::getObjectManager()->get(DataObjectHelper::class); -/** @var ProductRepositoryInterface $productRepository */ -$productRepository = $objectManager->get(ProductRepositoryInterface::class); - -$product = $productFactory->create(); -$productData = [ - ProductInterface::TYPE_ID => Type::TYPE_SIMPLE, - ProductInterface::ATTRIBUTE_SET_ID => 4, - ProductInterface::SKU => 'simple_product', - ProductInterface::NAME => 'Simple Product', - ProductInterface::PRICE => 20, - ProductInterface::VISIBILITY => Visibility::VISIBILITY_BOTH, - ProductInterface::STATUS => Status::STATUS_ENABLED, -]; -$dataObjectHelper->populateWithArray($product, $productData, ProductInterface::class); -/** Out of interface */ -$product - ->setWebsiteIds([1]) - ->setStockData( - [ - 'qty' => 85.5, - 'is_in_stock' => true, - 'manage_stock' => true, - 'is_qty_decimal' => true - ] - ); -$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet_rollback.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet_rollback.php deleted file mode 100644 index 6b37585f8224f..0000000000000 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/_files/simple_product_authorizenet_rollback.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -// phpcs:ignore Magento2.Security.IncludeFile -require __DIR__ . '/../../GraphQl/Catalog/_files/simple_product_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/ConsecutiveCallTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/ConsecutiveCallTest.php new file mode 100644 index 0000000000000..aff706688dc9f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/ConsecutiveCallTest.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Backend\Controller\Adminhtml; + +use Magento\TestFramework\TestCase\AbstractBackendController; + +/** + * @magentoAppArea adminhtml + */ +class ConsecutiveCallTest extends AbstractBackendController +{ + /** + * Consecutive calls were failing due to `$request['dispatched']` not being reset before request + */ + public function testConsecutiveCallShouldNotFail() + { + $this->dispatch('backend/admin/auth/login'); + $this->dispatch('backend/admin/auth/login'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListProduct/SortingTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListProduct/SortingTest.php index 7bebf9c49d14b..31da969540d30 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListProduct/SortingTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListProduct/SortingTest.php @@ -110,16 +110,7 @@ public function testProductListSortOrder(string $sortBy, string $direction, arra */ public function testProductListSortOrderWithConfig(string $sortBy, string $direction, array $expectation): void { - $this->objectManager->removeSharedInstance(Config::class); - $this->scopeConfig->setValue( - Config::XML_PATH_LIST_DEFAULT_SORT_BY, - $sortBy, - ScopeInterface::SCOPE_STORE, - Store::DEFAULT_STORE_ID - ); - $category = $this->updateCategorySortBy('Category 1', Store::DEFAULT_STORE_ID, null); - $this->renderBlock($category, $direction); - $this->assertBlockSorting($sortBy, $expectation); + $this->assertProductListSortOrderWithConfig($sortBy, $direction, $expectation); } /** @@ -322,4 +313,89 @@ private function updateCategorySortBy( return $category; } + + /** + * Test product list ordered by price with out-of-stock configurable product options with elasticsearch engine + * + * @magentoDataFixture Magento/Catalog/_files/products_with_not_empty_layered_navigation_attribute.php + * @magentoDataFixture Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child.php + * @magentoConfigFixture current_store cataloginventory/options/show_out_of_stock 1 + * @magentoConfigFixture default/catalog/search/engine elasticsearch7 + * @dataProvider productListWithOutOfStockSortOrderDataProvider + * @param string $sortBy + * @param string $direction + * @param array $expected + * @return void + */ + public function testProductListOutOfStockSortOrderWithElasticsearch( + string $sortBy, + string $direction, + array $expected + ): void { + $this->assertProductListSortOrderWithConfig($sortBy, $direction, $expected); + } + + /** + * Test product list ordered by price with out-of-stock configurable product options with mysql search engine + * + * @magentoDataFixture Magento/Catalog/_files/products_with_not_empty_layered_navigation_attribute.php + * @magentoDataFixture Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child.php + * @magentoConfigFixture current_store cataloginventory/options/show_out_of_stock 1 + * @magentoConfigFixture default/catalog/search/engine mysql + * @dataProvider productListWithOutOfStockSortOrderDataProvider + * @param string $sortBy + * @param string $direction + * @param array $expected + * @return void + */ + public function testProductListOutOfStockSortOrderWithMysql( + string $sortBy, + string $direction, + array $expected + ): void { + $this->assertProductListSortOrderWithConfig($sortBy, $direction, $expected); + } + + /** + * Product list with out-of-stock sort order data provider + * + * @return array + */ + public function productListWithOutOfStockSortOrderDataProvider(): array + { + return [ + 'default_order_price_asc' => [ + 'sort' => 'price', + 'direction' => Collection::SORT_ORDER_ASC, + 'expectation' => ['simple1', 'simple2', 'simple3', 'configurable'], + ], + 'default_order_price_desc' => [ + 'sort' => 'price', + 'direction' => Collection::SORT_ORDER_DESC, + 'expectation' => ['simple3', 'simple2', 'simple1', 'configurable'], + ], + ]; + } + + /** + * Assert product list order + * + * @param string $sortBy + * @param string $direction + * @param array $expected + * @return void + */ + private function assertProductListSortOrderWithConfig(string $sortBy, string $direction, array $expected): void + { + $this->objectManager->removeSharedInstance(Config::class); + $this->scopeConfig->setValue( + Config::XML_PATH_LIST_DEFAULT_SORT_BY, + $sortBy, + ScopeInterface::SCOPE_STORE, + Store::DEFAULT_STORE_ID + ); + $category = $this->updateCategorySortBy('Category 1', Store::DEFAULT_STORE_ID, null); + $this->renderBlock($category, $direction); + $this->assertBlockSorting($sortBy, $expected); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListTest.php index 6c735e52f8c1a..25e26bc66ab51 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ListTest.php @@ -92,8 +92,10 @@ public function testGetAdditionalHtml() public function testSetCollection() { - $this->_block->setCollection('test'); - $this->assertEquals('test', $this->_block->getLoadedProductCollection()); + $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Framework\Data\Collection::class); + $this->_block->setCollection($collection); + $this->assertEquals($collection, $this->_block->getLoadedProductCollection()); } public function testGetPriceBlockTemplate() diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layout/DepersonalizePluginTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layout/DepersonalizePluginTest.php new file mode 100644 index 0000000000000..43b5422dbb90a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layout/DepersonalizePluginTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model\Layout; + +use Magento\Catalog\Model\Session as CatalogSession; +use Magento\Framework\App\Cache\Type\Layout as LayoutCache; +use Magento\Framework\View\Layout; +use Magento\Framework\View\LayoutFactory; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Integration tests for \Magento\Catalog\Model\Layout\DepersonalizePlugin class. + * + * @magentoAppArea frontend + */ +class DepersonalizePluginTest extends TestCase +{ + /** + * @var CatalogSession + */ + private $catalogSession; + + /** + * @var Layout + */ + private $layout; + + /** + * @var LayoutCache + */ + private $cache; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->catalogSession = Bootstrap::getObjectManager()->get(CatalogSession::class); + $this->layout = Bootstrap::getObjectManager()->get(LayoutFactory::class)->create(); + $this->cache = Bootstrap::getObjectManager()->get(LayoutCache::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->catalogSession->clearStorage(); + } + + /** + * @magentoCache full_page enabled + * @dataProvider afterGenerateElementsDataProvider + * + * @param string $layout + * @param array $expectedResult + * @return void + */ + public function testAfterGenerateElements(string $layout, array $expectedResult): void + { + $this->cache->clean(); + $this->assertTrue($this->layout->loadFile($layout)); + $this->catalogSession->setData(['some_data' => 1]); + $this->layout->generateElements(); + $this->assertEquals($expectedResult, $this->catalogSession->getData()); + } + + /** + * @return array + */ + public function afterGenerateElementsDataProvider(): array + { + return [ + 'cacheable' => [ + 'layout' => INTEGRATION_TESTS_DIR . '/testsuite/Magento/Framework/View/_files/layout/cacheable.xml', + 'expectedResult' => [], + ], + 'nonCacheable' => [ + 'layout' => INTEGRATION_TESTS_DIR . '/testsuite/Magento/Framework/View/_files/layout/non_cacheable.xml', + 'expectedResult' => ['some_data' => 1], + ], + 'nonCacheableBlockWithoutReference' => [ + 'layout' => INTEGRATION_TESTS_DIR + . '/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_missing_refference.xml', + 'expectedResult' => [], + ], + 'nonCacheableBlockWithExistedReference' => [ + 'layout' => INTEGRATION_TESTS_DIR + . '/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_declared_reference.xml', + 'expectedResult' => ['some_data' => 1], + ], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_tree_with_products.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_tree_with_products.php new file mode 100644 index 0000000000000..d98b1b738cf0d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_tree_with_products.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\CategoryRepositoryInterface; +use Magento\Catalog\Api\Data\ProductInterfaceFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Api\Data\CategoryInterfaceFactory; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Type; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Store\Model\Store; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Eav\Model\Config; + +$objectManager = Bootstrap::getObjectManager(); +$categoryFactory = $objectManager->get(CategoryInterfaceFactory::class); +$productFactory = $objectManager->get(ProductInterfaceFactory::class); +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$categoryRepository = $objectManager->get(CategoryRepositoryInterface::class); + +$categoryA = $categoryFactory->create( + [ + 'data' => [ + 'name' => 'Category A', + 'parent_id' => 2, + 'level' => 2, + 'position' => 1, + 'is_active' => true, + 'available_sort_by' =>['position', 'name'], + 'default_sort_by' => 'name', + ], + ] +); +$categoryA->isObjectNew(true); +$categoryA = $categoryRepository->save($categoryA); + +$categoryB = $categoryFactory->create( + [ + 'data' => [ + 'name' => 'Category B', + 'parent_id' => 2, + 'level' => 2, + 'position' => 1, + 'is_active' => true, + 'available_sort_by' =>['position', 'name'], + 'default_sort_by' => 'name', + ], + ] +); +$categoryB->isObjectNew(true); +$categoryB = $categoryRepository->save($categoryB); + +$categoryC = $categoryFactory->create( + [ + 'data' => [ + 'name' => 'Category C', + 'parent_id' => $categoryB->getId(), + 'level' => 2, + 'position' => 1, + 'is_active' => true, + 'available_sort_by' =>['position', 'name'], + 'default_sort_by' => 'name', + ], + ] +); +$categoryC->isObjectNew(true); +$categoryC = $categoryRepository->save($categoryC); + +$defaultAttributeSet = $objectManager->get(Config::class) + ->getEntityType('catalog_product') + ->getDefaultAttributeSetId(); +$product = $productFactory->create( + [ + 'data' => [ + 'type_id' => Type::TYPE_SIMPLE, + 'attribute_set_id' => $defaultAttributeSet, + 'store_id' => Store::DEFAULT_STORE_ID, + 'website_ids' => [1], + 'name' => 'Simple Product B', + 'sku' => 'simpleB', + 'price' => 10, + 'weight' => 1, + 'stock_data' => ['use_config_manage_stock' => 0], + 'category_ids' => [$categoryB->getId()], + 'visibility' => Visibility::VISIBILITY_BOTH, + 'status' => Status::STATUS_ENABLED, + ], + ] +); +$productRepository->save($product); + +$product = $productFactory->create( + [ + 'data' => [ + 'type_id' => Type::TYPE_SIMPLE, + 'attribute_set_id' => $defaultAttributeSet, + 'store_id' => Store::DEFAULT_STORE_ID, + 'website_ids' => [1], + 'name' => 'Simple Product C', + 'sku' => 'simpleC', + 'price' => 20, + 'weight' => 1, + 'stock_data' => ['use_config_manage_stock' => 0], + 'category_ids' => [$categoryC->getId()], + 'visibility' => Visibility::VISIBILITY_BOTH, + 'status' => Status::STATUS_ENABLED, + ], + ] +); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_tree_with_products_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_tree_with_products_rollback.php new file mode 100644 index 0000000000000..448bc60f50b90 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_tree_with_products_rollback.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\CategoryRepositoryInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); +$registry = $objectManager->get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$categoryRepository = $objectManager->get(CategoryRepositoryInterface::class); + +$productSkus = ['simpleB', 'simpleC']; + +foreach ($productSkus as $productSku) { + try { + $productRepository->deleteById($productSku); + } catch (NoSuchEntityException $e) { + //Already deleted. + } +} + +$categoriesNames = ['Category A', 'Category B', 'Category C']; + +foreach ($categoriesNames as $categoryName) { + try { + $category = $categoryRepository->get($categoryName); + $categoryRepository->delete($category); + } catch (NoSuchEntityException $e) { + //Already deleted. + } +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php index 508560d000271..1daa794165873 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php @@ -84,8 +84,10 @@ protected function setUp() /** * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php * @magentoDbIsolation enabled + * + * @return void */ - public function testExport() + public function testExport(): void { $this->model->setWriter( $this->objectManager->create( @@ -109,8 +111,10 @@ public function testExport() /** * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data_special_chars.php * @magentoDbIsolation enabled + * + * @return void */ - public function testExportSpecialChars() + public function testExportSpecialChars(): void { $this->model->setWriter( $this->objectManager->create( @@ -125,8 +129,10 @@ public function testExportSpecialChars() /** * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_with_product_links_data.php * @magentoDbIsolation enabled + * + * @return void */ - public function testExportWithProductLinks() + public function testExportWithProductLinks(): void { $this->model->setWriter( \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( @@ -143,8 +149,10 @@ public function testExportWithProductLinks() * @magentoDbIsolation enabled * @covers \Magento\CatalogImportExport\Model\Export\Product::export * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php + * + * @return void */ - public function testExportStockItemAttributesAreFilled() + public function testExportStockItemAttributesAreFilled(): void { $this->markTestSkipped('Test needs to be skipped.'); $fileWrite = $this->createMock(\Magento\Framework\Filesystem\File\Write::class); @@ -176,8 +184,9 @@ public function testExportStockItemAttributesAreFilled() * Verify header columns (that stock item attributes column headers are present) * * @param array $headerColumns + * @return void */ - public function verifyHeaderColumns(array $headerColumns) + public function verifyHeaderColumns(array $headerColumns): void { foreach (self::$stockItemAttributes as $stockItemAttribute) { $this->assertContains( @@ -192,8 +201,9 @@ public function verifyHeaderColumns(array $headerColumns) * Verify row data (stock item attribute values) * * @param array $rowData + * @return void */ - public function verifyRow(array $rowData) + public function verifyRow(array $rowData): void { foreach (self::$stockItemAttributes as $stockItemAttribute) { $this->assertNotSame( @@ -208,8 +218,10 @@ public function verifyRow(array $rowData) * Verifies if exception processing works properly * @magentoDbIsolation enabled * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php + * + * @return void */ - public function testExceptionInGetExportData() + public function testExceptionInGetExportData(): void { $this->markTestSkipped('Test needs to be skipped.'); $exception = new \Exception('Error'); @@ -258,8 +270,10 @@ public function testExceptionInGetExportData() * Verify if fields wrapping works correct when "Fields Enclosure" option enabled * * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php + * + * @return void */ - public function testExportWithFieldsEnclosure() + public function testExportWithFieldsEnclosure(): void { $this->model->setParameters( [ @@ -284,8 +298,10 @@ public function testExportWithFieldsEnclosure() * Verify that "category ids" filter correctly applies to export result * * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_with_categories.php + * + * @return void */ - public function testCategoryIdsFilter() + public function testCategoryIdsFilter(): void { $this->model->setWriter( $this->objectManager->create( @@ -313,8 +329,10 @@ public function testCategoryIdsFilter() * Verify that export processed successfully with wrong category path * * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_with_broken_categories_path.php + * + * @return void */ - public function testExportWithWrongCategoryPath() + public function testExportWithWrongCategoryPath(): void { $this->model->setWriter( $this->objectManager->create( @@ -329,8 +347,10 @@ public function testExportWithWrongCategoryPath() * Test 'hide from product page' export for non-default store. * * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_with_images.php + * + * @return void */ - public function testExportWithMedia() + public function testExportWithMedia(): void { /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); @@ -359,6 +379,7 @@ public function testExportWithMedia() /** * @magentoDataFixture Magento/CatalogImportExport/_files/product_export_data.php + * * @return void */ public function testExportWithCustomOptions(): void @@ -403,12 +424,19 @@ public function testExportWithCustomOptions(): void /** @var \Magento\Framework\File\Csv $csv */ $csv = $this->objectManager->get(\Magento\Framework\File\Csv::class); $data = $csv->getData($varDirectory->getAbsolutePath('test_product_with_custom_options_and_second_store.csv')); + $keys = array_shift($data); + $products = []; + foreach ($data as $productData) { + $products[] = array_combine($keys, $productData); + } + $products = array_filter($products, function (array $product) { + return $product['sku'] === 'simple'; + }); $customOptionData = []; - foreach ($data[0] as $columnNumber => $columnName) { - if ($columnName === 'custom_options') { - $customOptionData['admin_store'] = $this->parseExportedCustomOption($data[1][$columnNumber]); - $customOptionData[$storeCode] = $this->parseExportedCustomOption($data[2][$columnNumber]); - } + + foreach ($products as $product) { + $storeCode = $product['store_view_code'] ?: 'admin_store'; + $customOptionData[$storeCode] = $this->parseExportedCustomOption($product['custom_options']); } self::assertSame($expectedData, $customOptionData); @@ -418,8 +446,10 @@ public function testExportWithCustomOptions(): void * Check that no duplicate entities when multiple custom options used * * @magentoDataFixture Magento/Catalog/_files/product_simple_with_options.php + * + * @return void */ - public function testExportWithMultipleOptions() + public function testExportWithMultipleOptions(): void { $expectedCount = 1; $resultsFilename = 'export_results.csv'; @@ -442,6 +472,8 @@ public function testExportWithMultipleOptions() } /** + * Parse exported custom options + * * @param string $exportedCustomOption * @return array */ @@ -476,8 +508,10 @@ function ($input) { * @magentoConfigFixture current_store catalog/price/scope 1 * @magentoDbIsolation disabled * @magentoAppArea adminhtml + * + * @return void */ - public function testExportProductWithTwoWebsites() + public function testExportProductWithTwoWebsites(): void { $globalStoreCode = 'admin'; $secondStoreCode = 'fixture_second_store'; @@ -539,17 +573,19 @@ public function testExportProductWithTwoWebsites() /** * Verify that "stock status" filter correctly applies to export result * + * @magentoDataFixture Magento/Catalog/_files/multiple_products_with_few_out_of_stock.php + * @dataProvider filterByQuantityAndStockStatusDataProvider + * * @param string $value * @param array $productsIncluded * @param array $productsNotIncluded - * @magentoDataFixture Magento/Catalog/_files/multiple_products_with_few_out_of_stock.php - * @dataProvider filterByQuantityAndStockStatusDataProvider + * @return void */ public function testFilterByQuantityAndStockStatus( string $value, array $productsIncluded, array $productsNotIncluded - ) { + ): void { $exportData = $this->doExport(['quantity_and_stock_status' => $value]); foreach ($productsIncluded as $productName) { $this->assertContains($productName, $exportData); @@ -569,35 +605,37 @@ public function filterByQuantityAndStockStatusDataProvider(): array [ 'Simple Product OOS', 'Simple Product Not Visible', - 'Simple Product Visible and InStock' + 'Simple Product Visible and InStock', ], [ - ] + ], ], [ '1', [ 'Simple Product Not Visible', - 'Simple Product Visible and InStock' + 'Simple Product Visible and InStock', ], [ - 'Simple Product OOS' - ] + 'Simple Product OOS', + ], ], [ '0', [ - 'Simple Product OOS' + 'Simple Product OOS', ], [ 'Simple Product Not Visible', - 'Simple Product Visible and InStock' - ] - ] + 'Simple Product Visible and InStock', + ], + ], ]; } /** + * Perform export + * * @param array $filters * @return string */ diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php index 477494626b9fb..865cba4998e30 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php @@ -59,8 +59,6 @@ $productModel->setTypeId( \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE -)->setId( - 1 )->setAttributeSetId( 4 )->setName( diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AttributeTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AttributeTest.php new file mode 100644 index 0000000000000..c789183069c10 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/Fulltext/Plugin/AttributeTest.php @@ -0,0 +1,141 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogSearch\Model\Indexer\Fulltext\Plugin; + +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; +use Magento\CatalogSearch\Model\Indexer\Fulltext\Processor; +use Magento\Catalog\Api\Data\EavAttributeInterface; + +/** + * Check catalogsearch_fulltext index status after create product attribute. + */ +class AttributeTest extends TestCase +{ + /** + * @var Processor + */ + private $indexerProcessor; + + /** + * @var Attribute + */ + private $attribute; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->indexerProcessor = Bootstrap::getObjectManager()->create(Processor::class); + $this->attribute = Bootstrap::getObjectManager()->create(Attribute::class); + } + + /** + * Check index status on clean database. + * + * @magentoDataFixture Magento/CatalogSearch/_files/full_reindex.php + */ + public function testCheckIndexStatusOnCleanDatabase(): void + { + $this->assertTrue($this->indexerProcessor->getIndexer()->isValid()); + } + + /** + * Check index status after create non searchable attribute. + * + * @return void + * @magentoDataFixture Magento/Catalog/_files/dropdown_attribute.php + * @magentoDbIsolation enabled + * @depends testCheckIndexStatusOnCleanDatabase + */ + public function testCheckIndexStatusAfterCreateNonSearchableAttribute(): void + { + $this->assertTrue($this->indexerProcessor->getIndexer()->isValid()); + } + + /** + * Check index status after non searchable attribute update. + * + * @return void + * @magentoDataFixture Magento/Catalog/_files/dropdown_attribute.php + * @magentoDbIsolation enabled + * @depends testCheckIndexStatusOnCleanDatabase + */ + public function testCheckIndexStatusAfterNonSearchableAttributeUpdate(): void + { + $this->attribute->load('dropdown_attribute', 'attribute_code'); + $this->assertFalse($this->attribute->isObjectNew()); + $this->attribute->setIsGlobal(1)->save(); + $this->assertTrue($this->indexerProcessor->getIndexer()->isValid()); + } + + /** + * Check index status after create searchable attribute. + * + * @return void + * @magentoDataFixture Magento/CatalogSearch/_files/search_attributes.php + * @magentoDbIsolation enabled + * @depends testCheckIndexStatusOnCleanDatabase + */ + public function testCheckIndexStatusAfterCreateSearchableAttribute(): void + { + $this->assertTrue($this->indexerProcessor->getIndexer()->isInvalid()); + } + + /** + * Check index status after update non searchable attribute to searchable. + * + * @param string $field + * @return void + * @dataProvider searchableAttributesDataProvider + * @magentoDataFixture Magento/Catalog/_files/dropdown_attribute.php + * @magentoDbIsolation enabled + */ + public function testCheckIndexStatusAfterUpdateNonSearchableAttributeToSearchable(string $field): void + { + $this->indexerProcessor->reindexAll(); + $this->assertTrue($this->indexerProcessor->getIndexer()->isValid()); + $this->attribute->loadByCode(Product::ENTITY, 'dropdown_attribute'); + $this->assertFalse($this->attribute->isObjectNew()); + $this->attribute->setData($field, true)->save(); + $this->assertFalse($this->indexerProcessor->getIndexer()->isValid()); + } + + /** + * @return array + */ + public function searchableAttributesDataProvider(): array + { + return [ + [EavAttributeInterface::IS_SEARCHABLE], + [EavAttributeInterface::IS_FILTERABLE], + [EavAttributeInterface::IS_VISIBLE_IN_ADVANCED_SEARCH] + ]; + } + + /** + * Check index status after update searchable attribute to non searchable. + * + * @return void + * @magentoDataFixture Magento/CatalogSearch/_files/search_attributes.php + * @magentoDbIsolation enabled + * @depends testCheckIndexStatusOnCleanDatabase + */ + public function testCheckIndexStatusAfterUpdateSearchableAttributeToNonSearchable(): void + { + $this->indexerProcessor->reindexAll(); + $this->assertTrue($this->indexerProcessor->getIndexer()->isValid()); + $this->attribute->loadByCode(Product::ENTITY, 'test_catalog_view'); + $this->assertFalse($this->attribute->isObjectNew()); + $this->attribute->setIsFilterable(false)->save(); + $this->assertFalse($this->indexerProcessor->getIndexer()->isValid()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php index b75a984178f24..f0c8402c51879 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php @@ -48,46 +48,6 @@ protected function setUp() ->create(\Magento\CatalogSearch\Model\Layer\Filter\Decimal::class, ['layer' => $layer]); $this->_model->setAttributeModel($attribute); } - - /** - * Test the filter label is correct - */ - public function testApplyFilterLabel() - { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var $request \Magento\TestFramework\Request */ - $request = $objectManager->get(\Magento\TestFramework\Request::class); - $request->setParam('weight', '10-20'); - $this->_model->apply($request); - - $filters = $this->_model->getLayer()->getState()->getFilters(); - $this->assertArrayHasKey(0, $filters); - $this->assertEquals( - '<span class="price">$10.00</span> - <span class="price">$19.99</span>', - (string)$filters[0]->getLabel() - ); - } - - /** - * Test the filter label is correct when there is empty To value - */ - public function testApplyFilterLabelWithEmptyToValue() - { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var $request \Magento\TestFramework\Request */ - $request = $objectManager->get(\Magento\TestFramework\Request::class); - $request->setParam('weight', '10-'); - $this->_model->apply($request); - - $filters = $this->_model->getLayer()->getState()->getFilters(); - $this->assertArrayHasKey(0, $filters); - $this->assertEquals( - '<span class="price">$10.00</span> and above', - (string)$filters[0]->getLabel() - ); - } public function testApplyNothing() { diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php index a7944566eb8e0..232b4ec00973a 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php @@ -37,16 +37,10 @@ protected function setUp() $category->load(4); $layer = $this->objectManager->get(\Magento\Catalog\Model\Layer\Category::class); $layer->setCurrentCategory($category); - /** @var $attribute \Magento\Catalog\Model\Entity\Attribute */ - $attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Entity\Attribute::class - ); - $attribute->loadByCode('catalog_product', 'price'); $this->_model = $this->objectManager->create( \Magento\CatalogSearch\Model\Layer\Filter\Price::class, ['layer' => $layer] ); - $this->_model->setAttributeModel($attribute); } public function testApplyNothing() @@ -91,9 +85,9 @@ public function testApplyWithCustomCurrencyRate() $request->setParam('price', '10-20'); $this->_model->setCurrencyRate(10); - + $this->_model->apply($request); - + $filters = $this->_model->getLayer()->getState()->getFilters(); $this->assertArrayHasKey(0, $filters); $this->assertEquals( diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Account/EmailTemplateTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Account/EmailTemplateTest.php new file mode 100644 index 0000000000000..ac12dc4df8d64 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Account/EmailTemplateTest.php @@ -0,0 +1,204 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Customer\Controller\Account; + +use Magento\Customer\Model\Session; +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Data\Form\FormKey; +use Magento\Framework\Mail\EmailMessage; +use Magento\Framework\Message\MessageInterface; +use Magento\TestFramework\Mail\Template\TransportBuilderMock; +use Magento\TestFramework\TestCase\AbstractController; + +/** + * Set of tests to verify e-mail templates delivered to Customers + * + * @magentoAppArea frontend + */ +class EmailTemplateTest extends AbstractController +{ + private const FIXTURE_CUSTOMER_EMAIL = 'customer@example.com'; + private const FIXTURE_CUSTOMER_FIRSTNAME = 'John'; + private const FIXTURE_CUSTOMER_LASTNAME = 'Smith'; + private const FIXTURE_CUSTOMER_ID = 1; + private const FIXTURE_CUSTOMER_PASSWORD = 'password'; + private const EXPECTED_GREETING = self::FIXTURE_CUSTOMER_FIRSTNAME . ' ' . self::FIXTURE_CUSTOMER_LASTNAME . ','; + + /** + * @var TransportBuilderMock + */ + private $transportBuilderMock; + + /** + * @var Session + */ + private $session; + + /** + * @var FormKey + */ + private $formKey; + + protected function setUp() + { + parent::setUp(); + $this->transportBuilderMock = $this->_objectManager->get(TransportBuilderMock::class); + $this->session = $this->_objectManager->get(Session::class); + $this->formKey = $this->_objectManager->get(FormKey::class); + } + + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoConfigFixture current_store customer/captcha/enable 0 + */ + public function testForgotPasswordEmailTemplateGreeting() + { + $this->getRequest()->setMethod(HttpRequest::METHOD_POST) + ->setPostValue(['email' => self::FIXTURE_CUSTOMER_EMAIL]); + $this->dispatch('customer/account/forgotPasswordPost'); + + $this->assertSameGreeting(self::EXPECTED_GREETING, $this->transportBuilderMock->getSentMessage()); + } + + /** + * Covers Magento_Customer::view/frontend/email/change_email.html + * + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoConfigFixture current_store customer/captcha/enable 0 + */ + public function testCustomerEmailChangeNotificationTemplateGreeting() + { + $this->loginByCustomerId(self::FIXTURE_CUSTOMER_ID); + + $this->sendAccountEditRequest([ + 'email' => 'new.email@example.com', + 'change_email' => 1, + ]); + + $this->assertRedirect($this->stringContains('customer/account/')); + $this->assertSessionMessages( + $this->equalTo(['You saved the account information.']), + MessageInterface::TYPE_SUCCESS + ); + + $this->assertSameGreeting(self::EXPECTED_GREETING, $this->transportBuilderMock->getSentMessage()); + } + + /** + * Covers Magento_Customer::view/frontend/email/change_email_and_password.html + * + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoConfigFixture current_store customer/captcha/enable 0 + */ + public function testCustomerEmailAndPasswordChangeNotificationTemplateGreeting() + { + $this->loginByCustomerId(self::FIXTURE_CUSTOMER_ID); + + $this->sendAccountEditRequest([ + 'email' => 'new.email@example.com', + 'change_email' => 1, + 'change_password' => 1, + 'password' => 'new-Password1', + 'password_confirmation' => 'new-Password1', + ]); + + $this->assertRedirect($this->stringContains('customer/account/')); + $this->assertSessionMessages( + $this->equalTo(['You saved the account information.']), + MessageInterface::TYPE_SUCCESS + ); + + $this->assertSameGreeting(self::EXPECTED_GREETING, $this->transportBuilderMock->getSentMessage()); + } + + /** + * Covers Magento_Customer::view/frontend/email/change_password.html + * + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoConfigFixture current_store customer/captcha/enable 0 + */ + public function testCustomerPasswordChangeNotificationTemplateGreeting() + { + $this->loginByCustomerId(self::FIXTURE_CUSTOMER_ID); + + $this->sendAccountEditRequest([ + 'change_password' => 1, + 'password' => 'new-Password1', + 'password_confirmation' => 'new-Password1', + ]); + + $this->assertRedirect($this->stringContains('customer/account/')); + $this->assertSessionMessages( + $this->equalTo(['You saved the account information.']), + MessageInterface::TYPE_SUCCESS + ); + + $this->assertSameGreeting(self::EXPECTED_GREETING, $this->transportBuilderMock->getSentMessage()); + } + + /** + * Wraps Customer Edit POST request + * + * @param array $customData + */ + private function sendAccountEditRequest(array $customData): void + { + $basicData = [ + 'form_key' => $this->formKey->getFormKey(), + 'firstname' => self::FIXTURE_CUSTOMER_FIRSTNAME, + 'lastname' => self::FIXTURE_CUSTOMER_LASTNAME, + 'current_password' => self::FIXTURE_CUSTOMER_PASSWORD + ]; + + $this->getRequest()->setMethod(HttpRequest::METHOD_POST) + ->setPostValue(array_merge($basicData, $customData)); + + $this->dispatch('customer/account/editPost'); + } + + /** + * Verifies if `<p class="greeting"/>` text contents equals the expected one. + * + * @param string $expectedGreeting + * @param EmailMessage $message + */ + private function assertSameGreeting(string $expectedGreeting, EmailMessage $message) + { + $messageContent = $this->getMessageRawContent($message); + $emailDom = new \DOMDocument(); + $emailDom->loadHTML($messageContent); + + $emailXpath = new \DOMXPath($emailDom); + $greeting = $emailXpath->query('//p[@class="greeting"]'); + + $this->assertSame(1, $greeting->length); + $this->assertSame($expectedGreeting, $greeting->item(0)->textContent); + } + + /** + * Returns raw content of provided message + * + * @param EmailMessage $message + * @return string + */ + private function getMessageRawContent(EmailMessage $message): string + { + $emailParts = $message->getBody()->getParts(); + return current($emailParts)->getRawContent(); + } + + /** + * Performs Customer log in + * + * @param int $customerId + */ + private function loginByCustomerId(int $customerId): void + { + $this->session->loginById($customerId); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index 7b0a4823f701e..55e970a178e91 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -189,14 +189,14 @@ public function testCreatepasswordActionInvalidToken() } /** - * @param int $customerId + * @param int $customerId * @param string|null $confirmation */ private function assertCustomerConfirmationEquals(int $customerId, string $confirmation = null) { /** @var \Magento\Customer\Model\Customer $customer */ $customer = Bootstrap::getObjectManager() - ->create(\Magento\Customer\Model\Customer::class)->load($customerId); + ->create(\Magento\Customer\Model\Customer::class)->load($customerId); $this->assertEquals($confirmation, $customer->getConfirmation()); } @@ -497,14 +497,14 @@ public function testChangePasswordEditPostAction() ->setMethod('POST') ->setPostValue( [ - 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(), - 'firstname' => 'John', - 'lastname' => 'Doe', - 'email' => 'johndoe@email.com', - 'change_password' => 1, - 'change_email' => 1, + 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(), + 'firstname' => 'John', + 'lastname' => 'Doe', + 'email' => 'johndoe@email.com', + 'change_password' => 1, + 'change_email' => 1, 'current_password' => 'password', - 'password' => 'new-Password1', + 'password' => 'new-Password1', 'password_confirmation' => 'new-Password1', ] ); @@ -654,6 +654,7 @@ public function testRegisterCustomerWithEmailConfirmation(): void /** @var CookieManagerInterface $cookieManager */ $cookieManager = $this->_objectManager->get(CookieManagerInterface::class); $cookieManager->deleteCookie(MessagePlugin::MESSAGES_COOKIES_NAME); + $this->_objectManager->removeSharedInstance(Http::class); $this->_objectManager->removeSharedInstance(Request::class); $this->_request = null; @@ -774,8 +775,9 @@ public function testResetPasswordWhenEmailChanged(): void $customer->setEmail($newEmail); $customerRepository->save($customer); - /* Goes through the link in a mail */ $this->resetRequest(); + + /* Goes through the link in a mail */ $this->getRequest() ->setParam('token', $token) ->setParam('id', $customerData->getId()); @@ -855,15 +857,13 @@ private function assertForgotPasswordEmailContent(string $token): void } /** - * Clear request object. - * - * @return void + * @inheritDoc */ - private function resetRequest(): void + protected function resetRequest(): void { $this->_objectManager->removeSharedInstance(Http::class); $this->_objectManager->removeSharedInstance(Request::class); - $this->_request = null; + parent::resetRequest(); } /** diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Customer/InvalidateTokenTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Customer/InvalidateTokenTest.php new file mode 100644 index 0000000000000..396824b44304d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Customer/InvalidateTokenTest.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Customer\Controller\Adminhtml\Customer; + +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Escaper; +use Magento\Framework\Message\MessageInterface; +use Magento\TestFramework\TestCase\AbstractBackendController; + +/** + * Invalidate customer token tests. + * + * @magentoAppArea adminhtml + * @magentoDbIsolation enabled + */ +class InvalidateTokenTest extends AbstractBackendController +{ + /** @var Escaper */ + private $escaper; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->escaper = $this->_objectManager->get(Escaper::class); + } + + /** + * @magentoDataFixture Magento/Integration/_files/customer_with_integration_token.php + * + * @return void + */ + public function testInvalidateCustomerToken(): void + { + $customerId = 1; + $this->getRequest()->setParam('customer_id', $customerId)->setMethod(HttpRequest::METHOD_GET); + $this->dispatch('backend/customer/customer/invalidateToken'); + $this->assertRedirect($this->stringContains('backend/customer/index/edit/id/' . $customerId)); + $message = $this->escaper->escapeHtml('You have revoked the customer\'s tokens.'); + $this->assertSessionMessages($this->equalTo([(string)__($message)]), MessageInterface::TYPE_SUCCESS); + } + + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + * + * @return void + */ + public function testInvalidateCustomerWithoutToken(): void + { + $customerId = 1; + $this->getRequest()->setParam('customer_id', $customerId)->setMethod(HttpRequest::METHOD_GET); + $this->dispatch('backend/customer/customer/invalidateToken'); + $this->assertRedirect($this->stringContains('backend/customer/index/edit/id/' . $customerId)); + $this->assertSessionMessages( + $this->equalTo([(string)__('This customer has no tokens.')]), + MessageInterface::TYPE_ERROR + ); + } + + /** + * @return void + */ + public function testInvalidateCustomerTokenWithoutParams(): void + { + $this->getRequest()->setMethod(HttpRequest::METHOD_GET); + $this->dispatch('backend/customer/customer/invalidateToken'); + $this->assertRedirect($this->stringContains('backend/customer/index/index')); + $message = $this->escaper->escapeHtml('We can\'t find a customer to revoke.'); + $this->assertSessionMessages($this->equalTo([(string)__($message)]), MessageInterface::TYPE_ERROR); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagement/CreateAccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagement/CreateAccountTest.php index 8be3dfc10d86e..28fefd0bc4e1b 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagement/CreateAccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/AccountManagement/CreateAccountTest.php @@ -19,6 +19,7 @@ use Magento\Framework\Encryption\EncryptorInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\State\InputMismatchException; use Magento\Framework\Math\Random; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Validator\Exception; @@ -496,9 +497,33 @@ public function testCreateNewCustomerFromClone(): void $this->assertCustomerData($customer, $expectedCustomerData); $this->accountManagement->authenticate( $customer->getEmail(), - '_aPassword1', - true + '_aPassword1' + ); + } + + /** + * Test for create customer account for second website (with existing email for default website) + * with global account scope config. + * + * @magentoConfigFixture current_store customer/account_share/scope 0 + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * + * @return void + */ + public function testCreateAccountInGlobalScope(): void + { + $customerEntity = $this->customerFactory->create(); + $this->dataObjectHelper->populateWithArray( + $customerEntity, + $this->defaultCustomerData, + CustomerInterface::class ); + $storeId = $this->storeManager->getStore('fixture_second_store')->getStoreId(); + $customerEntity->setStoreId($storeId); + $message = 'A customer with the same email address already exists in an associated website.'; + $this->expectExceptionObject(new InputMismatchException(__($message))); + $this->accountManagement->createAccount($customerEntity, '_aPassword1'); } /** diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/ShareTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/ShareTest.php index 0c35155e5f213..f8371ee959bae 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/ShareTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/ShareTest.php @@ -3,43 +3,80 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Customer\Model\Config; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Api\WebsiteRepositoryInterface; use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; /** * Test \Magento\Customer\Model\Config\Share */ -class ShareTest extends \PHPUnit\Framework\TestCase +class ShareTest extends TestCase { - public function testGetSharedWebsiteIds() + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Share */ + private $share; + + /** @var WebsiteRepositoryInterface */ + private $websiteRepository; + + /** + * @inheritdoc + */ + protected function setUp() { - /** @var Share $share */ - $share = Bootstrap::getObjectManager()->get(\Magento\Customer\Model\Config\Share::class); + parent::setUp(); - $websiteIds = $share->getSharedWebsiteIds(42); + $this->objectManager = Bootstrap::getObjectManager(); + $this->share = $this->objectManager->get(Share::class); + $this->websiteRepository = $this->objectManager->create(WebsiteRepositoryInterface::class); + } + /** + * @return void + */ + public function testGetSharedWebsiteIds(): void + { + $websiteIds = $this->share->getSharedWebsiteIds(42); $this->assertEquals([42], $websiteIds); } /** * @magentoDataFixture Magento/Store/_files/core_second_third_fixturestore.php * @magentoConfigFixture current_store customer/account_share/scope 0 + * + * @return void */ - public function testGetSharedWebsiteIdsMultipleSites() + public function testGetSharedWebsiteIdsMultipleSites(): void { - /** @var Share $share */ - $share = Bootstrap::getObjectManager()->get(\Magento\Customer\Model\Config\Share::class); - $expectedIds = [1]; - /** @var \Magento\Store\Model\Website $website */ - $website = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Store\Model\Website::class - ); - $expectedIds[] = $website->load('secondwebsite')->getId(); - $expectedIds[] = $website->load('thirdwebsite')->getId(); - - $websiteIds = $share->getSharedWebsiteIds(42); - + $expectedIds[] = $this->websiteRepository->get('base')->getId(); + $expectedIds[] = $this->websiteRepository->get('secondwebsite')->getId(); + $expectedIds[] = $this->websiteRepository->get('thirdwebsite')->getId(); + $websiteIds = $this->share->getSharedWebsiteIds(42); $this->assertEquals($expectedIds, $websiteIds); } + + /** + * @magentoConfigFixture current_store customer/account_share/scope 1 + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Customer/_files/customer_for_second_website.php + * @magentoDbIsolation enabled + * + * @return void + */ + public function testEnableGlobalAccountShareScope(): void + { + $message = 'We can\'t share customer accounts globally when the accounts share' + . ' identical email addresses on more than one website.'; + $this->expectExceptionObject(new LocalizedException(__($message))); + $this->share->setPath(Share::XML_PATH_CUSTOMER_ACCOUNT_SHARE)->setValue((string)Share::SHARE_GLOBAL) + ->beforeSave(); + } } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php index 9f121268135f8..7ca0e759c8408 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php @@ -23,6 +23,7 @@ public function testToOptionArray() $optionsToCompare = []; foreach ($options as $option) { if (is_array($option['value'])) { + //phpcs:ignore Magento2.Performance.ForeachArrayMerge $optionsToCompare = array_merge($optionsToCompare, $option['value']); } else { $optionsToCompare[] = $option; @@ -36,22 +37,18 @@ public function testToOptionArray() [ 'value' => 1, 'label' => 'Default (General)', - '__disableTmpl' => true, ], [ 'value' => 1, 'label' => 'General', - '__disableTmpl' => true, ], [ 'value' => 2, 'label' => 'Wholesale', - '__disableTmpl' => true, ], [ 'value' => 3, 'label' => 'Retailer', - '__disableTmpl' => true, ], ] ); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerRegistryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerRegistryTest.php index d885d7c6f36e0..7bff71bb85bf8 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerRegistryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerRegistryTest.php @@ -3,127 +3,195 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Customer\Model; +use Magento\Customer\Model\ResourceModel\Customer as CustomerResourceModel; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Model\StoreManagerInterface; use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; /** * Test for \Magento\Customer\Model\CustomerRegistry + * + * @magentoDbIsolation enabled */ -class CustomerRegistryTest extends \PHPUnit\Framework\TestCase +class CustomerRegistryTest extends TestCase { /** - * @var \Magento\Customer\Model\CustomerRegistry + * @var ObjectManagerInterface */ - protected $_model; + private $objectManager; - /**#@+ - * Data set in customer fixture + /** + * @var CustomerRegistry + */ + private $model; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var CustomerResourceModel */ - const CUSTOMER_ID = 1; - const CUSTOMER_EMAIL = 'customer@example.com'; - const WEBSITE_ID = 1; + private $customerResourceModel; /** - * Initialize SUT + * @var int + */ + private $defaultWebsiteId; + + /** + * @inheritdoc */ protected function setUp() { - $this->_model = Bootstrap::getObjectManager() - ->create(\Magento\Customer\Model\CustomerRegistry::class); + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->model = $this->objectManager->get(CustomerRegistry::class); + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + $this->customerResourceModel = $this->objectManager->get(CustomerResourceModel::class); + $this->defaultWebsiteId = $this->storeManager->getWebsite('base')->getWebsiteId(); } /** * @magentoDataFixture Magento/Customer/_files/customer.php + * + * @return void */ - public function testRetrieve() + public function testRetrieve(): void { - $customer = $this->_model->retrieve(self::CUSTOMER_ID); - $this->assertInstanceOf(\Magento\Customer\Model\Customer::class, $customer); - $this->assertEquals(self::CUSTOMER_ID, $customer->getId()); + $customer = $this->model->retrieve(1); + $this->assertInstanceOf(Customer::class, $customer); + $this->assertEquals(1, $customer->getId()); } /** * @magentoDataFixture Magento/Customer/_files/customer.php + * + * @return void */ - public function testRetrieveByEmail() + public function testRetrieveByEmail(): void { - $customer = $this->_model->retrieveByEmail('customer@example.com', self::WEBSITE_ID); - $this->assertInstanceOf(\Magento\Customer\Model\Customer::class, $customer); - $this->assertEquals(self::CUSTOMER_EMAIL, $customer->getEmail()); + $email = 'customer@example.com'; + $customer = $this->model->retrieveByEmail($email, $this->defaultWebsiteId); + $this->assertInstanceOf(Customer::class, $customer); + $this->assertEquals($email, $customer->getEmail()); } /** * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoAppArea adminhtml + * + * @return void */ - public function testRetrieveCached() + public function testRetrieveCached(): void { - //Setup customer in the id and email registries - $customerBeforeDeletion = $this->_model->retrieve(self::CUSTOMER_ID); - //Delete the customer from db - Bootstrap::getObjectManager()->create( - \Magento\Customer\Model\Customer::class - )->load(self::CUSTOMER_ID)->delete(); - //Verify presence of Customer in registry - $this->assertEquals($customerBeforeDeletion, $this->_model->retrieve(self::CUSTOMER_ID)); - //Verify presence of Customer in email registry - $this->assertEquals($customerBeforeDeletion, $this->_model - ->retrieveByEmail(self::CUSTOMER_EMAIL, self::WEBSITE_ID)); + $customerId = 1; + $customerBeforeDeletion = $this->model->retrieve($customerId); + $this->customerResourceModel->load($customerBeforeDeletion, $customerBeforeDeletion->getId()); + $this->customerResourceModel->delete($customerBeforeDeletion); + $this->assertEquals($customerBeforeDeletion, $this->model->retrieve($customerId)); + $this->assertEquals($customerBeforeDeletion, $this->model + ->retrieveByEmail('customer@example.com', $this->defaultWebsiteId)); } /** - * @expectedException \Magento\Framework\Exception\NoSuchEntityException - * @expectedExceptionMessage No such entity with customerId = 1 + * @return void */ - public function testRetrieveException() + public function testRetrieveException(): void { - $this->_model->retrieve(self::CUSTOMER_ID); + $customerId = 1; + $this->expectException(NoSuchEntityException::class); + $this->expectExceptionMessage(sprintf('No such entity with customerId = %s', $customerId)); + $this->model->retrieve($customerId); } - public function testRetrieveEmailException() + /** + * @return void + */ + public function testRetrieveEmailException(): void { - try { - $this->_model->retrieveByEmail(self::CUSTOMER_EMAIL, self::WEBSITE_ID); - $this->fail("NoSuchEntityException was not thrown as expected."); - } catch (NoSuchEntityException $e) { - $expectedParams = [ - 'fieldName' => 'email', - 'fieldValue' => 'customer@example.com', - 'field2Name' => 'websiteId', - 'field2Value' => 1, - ]; - $this->assertEquals($expectedParams, $e->getParameters()); - } + $email = 'customer@example.com'; + $this->expectExceptionObject( + NoSuchEntityException::doubleField('email', $email, 'websiteId', $this->defaultWebsiteId) + ); + $this->model->retrieveByEmail($email, $this->defaultWebsiteId); } /** * @magentoDataFixture Magento/Customer/_files/customer.php - * @expectedException \Magento\Framework\Exception\NoSuchEntityException * @magentoAppArea adminhtml + * + * @return void */ - public function testRemove() + public function testRemove(): void { - $customer = $this->_model->retrieve(self::CUSTOMER_ID); - $this->assertInstanceOf(\Magento\Customer\Model\Customer::class, $customer); - $customer->delete(); - $this->_model->remove(self::CUSTOMER_ID); - $this->_model->retrieve(self::CUSTOMER_ID); + $customerId = 1; + $customer = $this->model->retrieve($customerId); + $this->assertInstanceOf(Customer::class, $customer); + $this->customerResourceModel->delete($customer); + $this->model->remove($customerId); + $this->expectException(NoSuchEntityException::class); + $this->model->retrieve($customerId); } /** * @magentoDataFixture Magento/Customer/_files/customer.php - * @expectedException \Magento\Framework\Exception\NoSuchEntityException * @magentoAppArea adminhtml + * + * @return void + */ + public function testRemoveByEmail(): void + { + $email = 'customer@example.com'; + $customer = $this->model->retrieve(1); + $this->assertInstanceOf(Customer::class, $customer); + $this->customerResourceModel->delete($customer); + $this->model->removeByEmail($email, $this->defaultWebsiteId); + $this->expectException(NoSuchEntityException::class); + $this->model->retrieveByEmail($email, $customer->getWebsiteId()); + } + + /** + * Test customer is available for all websites with global account scope config. + * + * @magentoConfigFixture current_store customer/account_share/scope 0 + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * + * @return void + */ + public function testRetrieveAccountInGlobalScope(): void + { + $email = 'customer@example.com'; + $websiteId = $this->storeManager->getWebsite('test')->getWebsiteId(); + $customer = $this->model->retrieveByEmail($email, $websiteId); + $this->assertEquals($email, $customer->getEmail()); + } + + /** + * Test customer is not available for second website with account scope config per websites. + * + * @magentoConfigFixture current_store customer/account_share/scope 1 + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Store/_files/second_website_with_two_stores.php + * + * @return void */ - public function testRemoveByEmail() + public function testRetrieveAccountInWebsiteScope(): void { - $customer = $this->_model->retrieve(self::CUSTOMER_ID); - $this->assertInstanceOf(\Magento\Customer\Model\Customer::class, $customer); - $customer->delete(); - $this->_model->removeByEmail(self::CUSTOMER_EMAIL, self::WEBSITE_ID); - $this->_model->retrieveByEmail(self::CUSTOMER_EMAIL, $customer->getWebsiteId()); + $email = 'customer@example.com'; + $websiteId = $this->storeManager->getWebsite('test')->getWebsiteId(); + $this->expectExceptionObject( + NoSuchEntityException::doubleField('email', $email, 'websiteId', $websiteId) + ); + $this->model->retrieveByEmail($email, $websiteId); } } diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_website.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_website.php new file mode 100644 index 0000000000000..c4df3e9fc8137 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_website.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Customer\Api\AccountManagementInterface; +use Magento\Customer\Api\CustomerMetadataInterface; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Model\Data\CustomerFactory; +use Magento\Customer\Model\GroupManagement; +use Magento\Eav\Model\AttributeRepository; +use Magento\TestFramework\Helper\Bootstrap; + +require __DIR__ . '/../../../Magento/Store/_files/second_website_with_two_stores.php'; + +$objectManager = Bootstrap::getObjectManager(); +/** @var AccountManagementInterface $accountManagment */ +$accountManagment = $objectManager->get(AccountManagementInterface::class); +/** @var CustomerFactory $customerFactory */ +$customerFactory = $objectManager->get(CustomerFactory::class); +/** @var AttributeRepository $attributeRepository */ +$attributeRepository = $objectManager->get(AttributeRepository::class); +$gender = $attributeRepository->get(CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, CustomerInterface::GENDER) + ->getSource()->getOptionId('Male'); +$defaultGroupId = $objectManager->get(GroupManagement::class)->getDefaultGroup($store->getStoreId())->getId(); + +$customer = $customerFactory->create(); +$customer->setWebsiteId($websiteId) + ->setEmail('customer@example.com') + ->setGroupId($defaultGroupId) + ->setStoreId($store->getStoreId()) + ->setFirstname('John') + ->setLastname('Smith') + ->setDefaultBilling(1) + ->setDefaultShipping(1) + ->setGender($gender); + +$accountManagment->createAccount($customer, 'Apassword1'); diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_website_rollback.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_website_rollback.php new file mode 100644 index 0000000000000..2d2bd7b4587d3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_website_rollback.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\TestFramework\Helper\Bootstrap; + +require __DIR__ . '/../../../Magento/Store/_files/second_website_with_two_stores_rollback.php'; + +$objectManager = Bootstrap::getObjectManager(); +/** @var CustomerRepositoryInterface $customerRepository */ +$customerRepository = $objectManager->get(CustomerRepositoryInterface::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +try { + $customer = $customerRepository->get('customer@example.com', $websiteId); + $customerRepository->delete($customer); +} catch (NoSuchEntityException $e) { + //customer already deleted +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php b/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php index fec71206accd8..30e70bd8f10d6 100644 --- a/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php +++ b/dev/tests/integration/testsuite/Magento/Developer/Model/Logger/Handler/DebugTest.php @@ -139,7 +139,7 @@ public function testDebugInDeveloperMode() { $message = 'test message'; $this->reinitDebugHandler(State::MODE_DEVELOPER); - + $this->deploymentConfig->resetData(); $this->removeDebugLog(); $this->logger->debug($message); $this->assertFileExists($this->getDebuggerLogPath()); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Block/Account/LinkTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Block/Account/LinkTest.php new file mode 100644 index 0000000000000..8916fc4853b05 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Block/Account/LinkTest.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Downloadable\Block\Account; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\Result\Page; +use Magento\Framework\View\Result\PageFactory; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Checks My Downloadable Product link displaying in account dashboard + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class LinkTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Page */ + private $page; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->page = $this->objectManager->get(PageFactory::class)->create(); + } + + /** + * @return void + */ + public function testMyDownloadableProductLink(): void + { + $this->preparePage(); + $block = $this->page->getLayout()->getBlock('customer-account-navigation-downloadable-products-link'); + $this->assertNotFalse($block); + $html = $block->toHtml(); + $this->assertContains('downloadable/customer/products', $html); + $this->assertEquals('My Downloadable Products', strip_tags($html)); + } + + /** + * Prepare page before render + * + * @return void + */ + private function preparePage(): void + { + $this->page->addHandle([ + 'default', + 'customer_account', + ]); + $this->page->getLayout()->generateXml(); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Block/Customer/Products/ListProductsTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Block/Customer/Products/ListProductsTest.php new file mode 100644 index 0000000000000..b1f68043198ca --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Block/Customer/Products/ListProductsTest.php @@ -0,0 +1,181 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Downloadable\Block\Customer\Products; + +use Magento\Customer\Model\Session; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\InvoiceOrderInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Api\RefundOrderInterface; +use Magento\Sales\Model\OrderFactory; +use Magento\Sales\Model\OrderRepository; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Class to check My Downloadable products tab content + * + * @see ListProducts + * @magentoAppArea frontend + * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ListProductsTest extends TestCase +{ + /** @var string */ + private $downloadLinkXpath = "//a[contains(@href, 'downloadable/download/link') and contains(text(), '%s')]"; + + /** @var string */ + private $statusXpath = "//table[@id='my-downloadable-products-table']" + . "//td[@data-th='Status' and contains(text(), '%s')]"; + + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var LayoutInterface */ + private $layout; + + /** @var Session */ + private $customerSession; + + /** @var OrderRepositoryInterface */ + private $orderRepository; + + /** @var InvoiceOrderInterface */ + private $invoiceOrder; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->layout = $this->objectManager->get(LayoutInterface::class); + $this->customerSession = $this->objectManager->get(Session::class); + $this->orderRepository = $this->objectManager->get(OrderRepositoryInterface::class); + $this->invoiceOrder = $this->objectManager->get(InvoiceOrderInterface::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->customerSession->logout(); + + parent::tearDown(); + } + + /** + * @return void + */ + public function testNoItems(): void + { + $html = $this->createBlock()->toHtml(); + $this->assertContains((string)__('You have not purchased any downloadable products yet.'), strip_tags($html)); + } + + /** + * @magentoDataFixture Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php + * + * @return void + */ + public function testPendingOrder(): void + { + $this->customerSession->loginById(1); + $this->assertEquals( + 0, + Xpath::getElementsCountForXpath( + sprintf($this->downloadLinkXpath, 'Downloadable Product Link'), + $this->createBlock()->toHtml() + ), + 'The download link displayed' + ); + } + + /** + * @magentoDataFixture Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php + * + * @return void + */ + public function testCompleteOrder(): void + { + $order = $this->getOrder('100000001'); + $this->invoiceOrder->execute($order->getId()); + $this->customerSession->loginById(1); + $html = $this->createBlock()->toHtml(); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($this->downloadLinkXpath, 'Downloadable Product Link'), $html), + 'The download link is not found' + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($this->statusXpath, (string)__('Available')), $html), + 'Wrong status displayed' + ); + } + + /** + * @magentoDataFixture Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php + * + * @return void + */ + public function testClosedOrder(): void + { + $order = $this->getOrder('100000001'); + $this->invoiceOrder->execute($order->getId()); + $this->objectManager->removeSharedInstance(OrderRepository::class); + $refundOrder = $this->objectManager->create(RefundOrderInterface::class); + $refundOrder->execute($order->getId()); + $this->customerSession->loginById(1); + $html = $this->createBlock()->toHtml(); + $this->assertEquals( + 0, + Xpath::getElementsCountForXpath(sprintf($this->downloadLinkXpath, 'Downloadable Product Link'), $html), + 'The download link is displayed for closed order' + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($this->statusXpath, (string)__('Expired')), $html), + 'Wrong status displayed' + ); + } + + /** + * Load order by increment id + * + * @param $orderIncrementId + * @return OrderInterface + */ + private function getOrder($orderIncrementId): OrderInterface + { + $order = $this->objectManager->get(OrderFactory::class)->create(); + + return $order->loadByIncrementId($orderIncrementId); + } + + /** + * Create ProductsList block + * + * @return ListProducts + */ + private function createBlock(): ListProducts + { + $block = $this->objectManager->create(ListProducts::class); + $block->setTemplate('Magento_Downloadable::customer/products/list.phtml'); + $this->layout->addBlock($block, 'downloadable_customer_products_list'); + + return $block; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php new file mode 100644 index 0000000000000..be5fa49f48eeb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/order_with_customer_and_downloadable_product.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Downloadable\Api\Data\LinkInterface; +use Magento\Downloadable\Model\Product\Type; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Address; +use Magento\Sales\Model\Order\AddressFactory; +use Magento\Sales\Model\Order\ItemFactory; +use Magento\Sales\Model\Order\PaymentFactory; +use Magento\Sales\Model\OrderFactory; +use Magento\Store\Model\StoreManagerInterface; + +require __DIR__ . '/../../../Magento/Downloadable/_files/product_downloadable.php'; +require __DIR__ . '/../../../Magento/Customer/_files/customer.php'; + +$addressData = include __DIR__ . '/../../../Magento/Sales/_files/address_data.php'; +/** @var AddressFactory $addressFactory */ +$addressFactory = $objectManager->get(AddressFactory::class); +$billingAddress = $addressFactory->create(['data' => $addressData]); +$billingAddress->setAddressType(Address::TYPE_BILLING); +/** @var ItemFactory $orderItemFactory */ +$orderItemFactory = $objectManager->get(ItemFactory::class); +/** @var PaymentFactory $orderPaymentFactory */ +$orderPaymentFactory = $objectManager->get(PaymentFactory::class); +/** @var StoreManagerInterface $storeManager */ +$storeManager = $objectManager->get(StoreManagerInterface::class); +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->create(OrderRepositoryInterface::class); +/** @var OrderFactory $orderFactory */ +$orderFactory = $objectManager->get(OrderFactory::class); + +$payment = $orderPaymentFactory->create(); +$payment->setMethod('checkmo') + ->setAdditionalInformation('last_trans_id', '11122') + ->setAdditionalInformation( + 'metadata', + ['type' => 'free', 'fraudulent' => false] + ); +/** @var ProductInterface $product */ +$product = $productRepository->get('downloadable-product'); +/** @var LinkInterface $links */ +$links = $product->getExtensionAttributes()->getDownloadableProductLinks(); +$link = reset($links); + +$orderItem = $orderItemFactory->create(); +$orderItem->setProductId($product->getId()) + ->setQtyOrdered(1) + ->setBasePrice($product->getPrice()) + ->setProductOptions(['links' => [$link->getId()]]) + ->setPrice($product->getPrice()) + ->setRowTotal($product->getPrice()) + ->setProductType(Type::TYPE_DOWNLOADABLE) + ->setName($product->getName()) + ->setSku($product->getSku()); + +$order = $orderFactory->create(); +$order->setIncrementId('100000001') + ->setState(Order::STATE_PROCESSING) + ->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)) + ->setSubtotal(100) + ->setGrandTotal(100) + ->setBaseSubtotal(100) + ->setBaseGrandTotal(100) + ->setCustomerId($customer->getId()) + ->setCustomerEmail($customer->getEmail()) + ->setBillingAddress($billingAddress) + ->setStoreId($storeManager->getStore()->getId()) + ->addItem($orderItem) + ->setPayment($payment); + +$orderRepository->save($order); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/order_with_customer_and_downloadable_product_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/order_with_customer_and_downloadable_product_rollback.php new file mode 100644 index 0000000000000..c182a67495f89 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/order_with_customer_and_downloadable_product_rollback.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\OrderFactory; +use Magento\TestFramework\Downloadable\Model\RemoveLinkPurchasedByOrderIncrementId; + +require __DIR__ . '/../../../Magento/Customer/_files/customer_rollback.php'; +require __DIR__ . '/../../../Magento/Downloadable/_files/product_downloadable_rollback.php'; + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var RemoveLinkPurchasedByOrderIncrementId $removeLinkPurchasedByOrderIncrementId */ +$removeLinkPurchasedByOrderIncrementId = $objectManager->get(RemoveLinkPurchasedByOrderIncrementId::class); +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->get(OrderRepositoryInterface::class); +$orderIncrementIdToDelete = '100000001'; +$removeLinkPurchasedByOrderIncrementId->execute($orderIncrementIdToDelete); +/** @var OrderFactory $order */ +$order = $objectManager->get(OrderFactory::class)->create(); +$order->loadByIncrementId($orderIncrementIdToDelete); + +if ($order->getId()) { + $orderRepository->delete($order); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Catalog/Model/Indexer/Category/Product/Action/RowsTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Catalog/Model/Indexer/Category/Product/Action/RowsTest.php new file mode 100644 index 0000000000000..c3aced62eecd3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Catalog/Model/Indexer/Category/Product/Action/RowsTest.php @@ -0,0 +1,163 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Elasticsearch\Catalog\Model\Indexer\Category\Product\Action; + +use Magento\Catalog\Api\CategoryListInterface; +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Helper\DefaultCategory; +use Magento\Catalog\Model\Indexer\Category\Product\Action\Rows; +use Magento\CatalogSearch\Model\ResourceModel\Fulltext\SearchCollectionFactory; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; +use Magento\TestModuleCatalogSearch\Model\ElasticsearchVersionChecker; +use Magento\Framework\Search\EngineResolverInterface; + +/** + * Test for Magento\Catalog\Model\Indexer\Category\Product\Action\Rows class. + * This test executable with any configuration of ES and should not be deleted with removal of ES2. + * + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class RowsTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var string + */ + private $searchEngine; + + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var Rows + */ + private $rowsIndexer; + + /** + * @var DefaultCategory + */ + private $defaultCategoryHelper; + + /** + * @var SearchCollectionFactory + */ + private $fulltextSearchCollectionFactory; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->rowsIndexer = $this->objectManager->get(Rows::class); + $this->defaultCategoryHelper = $this->objectManager->get(DefaultCategory::class); + $this->fulltextSearchCollectionFactory = $this->objectManager->get(SearchCollectionFactory::class); + } + + /** + * @inheritdoc + */ + protected function assertPreConditions() + { + $currentEngine = $this->objectManager->get(EngineResolverInterface::class)->getCurrentSearchEngine(); + $this->assertEquals($this->getInstalledSearchEngine(), $currentEngine); + } + + /** + * Returns installed on server search service. + * + * @return string + */ + private function getInstalledSearchEngine(): string + { + if (!$this->searchEngine) { + // phpstan:ignore "Class Magento\TestModuleCatalogSearch\Model\ElasticsearchVersionChecker not found." + $version = $this->objectManager->get(ElasticsearchVersionChecker::class)->getVersion(); + $this->searchEngine = 'elasticsearch' . $version; + } + + return $this->searchEngine; + } + + /** + * @magentoDataFixture Magento/Catalog/_files/category_tree_with_products.php + * @magentoDataFixture Magento/CatalogSearch/_files/full_reindex.php + * @magentoConfigFixture current_store catalog/search/elasticsearch_index_prefix indexerhandlertest + * @magentoDataFixtureBeforeTransaction Magento/Catalog/_files/enable_reindex_schedule.php + * @return void + */ + public function testLoadWithFilterCatalogView() + { + $categoryA = $this->getCategory('Category A'); + $categoryB = $this->getCategory('Category B'); + $categoryC = $this->getCategory('Category C'); + + /** Move $categoryB to $categoryA */ + $categoryB->move($categoryA->getId(), null); + $this->rowsIndexer->execute( + [ + $this->defaultCategoryHelper->getId(), + $categoryA->getId(), + $categoryB->getId(), + $categoryC->getId(), + ], + true + ); + + $fulltextCollection = $this->fulltextSearchCollectionFactory->create() + ->addCategoryFilter($categoryA); + + $this->assertProductsArePresentInCollection($fulltextCollection->getAllIds()); + } + + /** + * Assert that expected products are present in collection. + * + * @param array $productIds + * + * @return void + */ + private function assertProductsArePresentInCollection(array $productIds): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + + $firstProductId = $productRepository->get('simpleB')->getId(); + $secondProductId = $productRepository->get('simpleC')->getId(); + + $this->assertCount(2, $productIds); + $this->assertContains($secondProductId, $productIds); + $this->assertContains($firstProductId, $productIds); + } + + /** + * Gets category by name. + * + * @param string $name + * @return CategoryInterface + */ + private function getCategory(string $name): CategoryInterface + { + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class); + $searchCriteria = $searchCriteriaBuilder->addFilter('name', $name) + ->create(); + /** @var CategoryListInterface $repository */ + $repository = $this->objectManager->get(CategoryListInterface::class); + $items = $repository->getList($searchCriteria) + ->getItems(); + + return array_pop($items); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/SortOrderBuilderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Api/SortOrderBuilderTest.php new file mode 100644 index 0000000000000..20b2528eb7918 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Api/SortOrderBuilderTest.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Api; + +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Test of building the Data Object + */ +class SortOrderBuilderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var SortOrderBuilder + */ + private $interceptedBuilder; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + $this->interceptedBuilder = Bootstrap::getObjectManager()->get(SortOrderBuilder::class . '\Interceptor'); + } + + /** + * Test Builder successfully creates object when Interceptor instance is provided. + * + * @return void + */ + public function testCreate(): void + { + $this->assertEquals(SortOrder::class, get_class($this->interceptedBuilder->create())); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock index 69b6d314ee64d..fbcaf8d1600fb 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.lock @@ -3124,79 +3124,6 @@ ], "description": "Authorization module provides access to Magento ACL functionality." }, - { - "name": "magento/module-authorizenet", - "version": "100.3.1", - "dist": { - "type": "zip", - "url": "https://repo.magento.com/archives/magento/module-authorizenet/magento-module-authorizenet-100.3.1.0.zip", - "reference": null, - "shasum": "ab9dc9018f1a5b71cfaa54c1975d6ee6b5c7610c" - }, - "require": { - "magento/framework": "102.0.*", - "magento/module-backend": "101.0.*", - "magento/module-catalog": "103.0.*", - "magento/module-checkout": "100.3.*", - "magento/module-payment": "100.3.*", - "magento/module-quote": "101.1.*", - "magento/module-sales": "102.0.*", - "magento/module-store": "101.0.*", - "php": "~7.1.3||~7.2.0" - }, - "suggest": { - "magento/module-config": "101.1.*" - }, - "type": "magento2-module", - "autoload": { - "files": [ - "registration.php" - ], - "psr-4": { - "Magento\\Authorizenet\\": "" - } - }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "description": "N/A" - }, - { - "name": "magento/module-authorizenet-acceptjs", - "version": "100.3.0", - "dist": { - "type": "zip", - "url": "https://repo.magento.com/archives/magento/module-authorizenet-acceptjs/magento-module-authorizenet-acceptjs-100.3.0.0.zip", - "reference": null, - "shasum": "16bc1b50a4e7f63bfa3869fa2c3bd4c67cedd8a3" - }, - "require": { - "magento/framework": "102.0.*", - "magento/module-backend": "101.0.*", - "magento/module-checkout": "100.3.*", - "magento/module-config": "101.1.*", - "magento/module-payment": "100.3.*", - "magento/module-quote": "101.1.*", - "magento/module-sales": "102.0.*", - "magento/module-store": "101.0.*", - "php": "~7.1.3||~7.2.0" - }, - "type": "magento2-module", - "autoload": { - "files": [ - "registration.php" - ], - "psr-4": { - "Magento\\AuthorizenetAcceptjs\\": "" - } - }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "description": "N/A" - }, { "name": "magento/module-backend", "version": "101.0.1", @@ -9666,8 +9593,6 @@ "magento/module-analytics": "100.3.1", "magento/module-asynchronous-operations": "100.3.1", "magento/module-authorization": "100.3.1", - "magento/module-authorizenet": "100.3.1", - "magento/module-authorizenet-acceptjs": "100.3.0", "magento/module-backend": "101.0.1", "magento/module-backup": "100.3.1", "magento/module-braintree": "100.3.1", diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock index 151c2b5eca565..6c51c6a2072e9 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.lock @@ -3124,79 +3124,6 @@ ], "description": "Authorization module provides access to Magento ACL functionality." }, - { - "name": "magento/module-authorizenet", - "version": "100.3.1", - "dist": { - "type": "zip", - "url": "https://repo.magento.com/archives/magento/module-authorizenet/magento-module-authorizenet-100.3.1.0.zip", - "reference": null, - "shasum": "ab9dc9018f1a5b71cfaa54c1975d6ee6b5c7610c" - }, - "require": { - "magento/framework": "102.0.*", - "magento/module-backend": "101.0.*", - "magento/module-catalog": "103.0.*", - "magento/module-checkout": "100.3.*", - "magento/module-payment": "100.3.*", - "magento/module-quote": "101.1.*", - "magento/module-sales": "102.0.*", - "magento/module-store": "101.0.*", - "php": "~7.1.3||~7.2.0" - }, - "suggest": { - "magento/module-config": "101.1.*" - }, - "type": "magento2-module", - "autoload": { - "files": [ - "registration.php" - ], - "psr-4": { - "Magento\\Authorizenet\\": "" - } - }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "description": "N/A" - }, - { - "name": "magento/module-authorizenet-acceptjs", - "version": "100.3.0", - "dist": { - "type": "zip", - "url": "https://repo.magento.com/archives/magento/module-authorizenet-acceptjs/magento-module-authorizenet-acceptjs-100.3.0.0.zip", - "reference": null, - "shasum": "16bc1b50a4e7f63bfa3869fa2c3bd4c67cedd8a3" - }, - "require": { - "magento/framework": "102.0.*", - "magento/module-backend": "101.0.*", - "magento/module-checkout": "100.3.*", - "magento/module-config": "101.1.*", - "magento/module-payment": "100.3.*", - "magento/module-quote": "101.1.*", - "magento/module-sales": "102.0.*", - "magento/module-store": "101.0.*", - "php": "~7.1.3||~7.2.0" - }, - "type": "magento2-module", - "autoload": { - "files": [ - "registration.php" - ], - "psr-4": { - "Magento\\AuthorizenetAcceptjs\\": "" - } - }, - "license": [ - "OSL-3.0", - "AFL-3.0" - ], - "description": "N/A" - }, { "name": "magento/module-backend", "version": "101.0.1", @@ -9666,8 +9593,6 @@ "magento/module-analytics": "100.3.1", "magento/module-asynchronous-operations": "100.3.1", "magento/module-authorization": "100.3.1", - "magento/module-authorizenet": "100.3.1", - "magento/module-authorizenet-acceptjs": "100.3.0", "magento/module-backend": "101.0.1", "magento/module-backup": "100.3.1", "magento/module-braintree": "100.3.1", diff --git a/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/ProfilerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/ProfilerTest.php index 99305ad2d4e80..5caa94b680c88 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/ProfilerTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/ProfilerTest.php @@ -10,7 +10,7 @@ use Magento\Framework\Config\ConfigOptionsListConstants; /** - * Class ProfilerTest + * Test profiler on database queries */ class ProfilerTest extends \PHPUnit\Framework\TestCase { @@ -140,7 +140,7 @@ public function testProfilerDuringSqlException() try { $connection->select()->from('unknown_table')->query()->fetch(); - } catch (\Zend_Db_Statement_Exception $exception) { + } catch (\Magento\Framework\DB\Adapter\TableNotFoundException $exception) { $this->assertNotEmpty($exception); } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child.php new file mode 100644 index 0000000000000..e46228e52a117 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\CategoryLinkManagementInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Helper\DefaultCategory; +use Magento\TestFramework\Helper\Bootstrap; + +require __DIR__ . '/product_configurable.php'; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(ProductRepositoryInterface::class); + +$product = $productRepository->get('simple_1010'); +$product->setStockData( + [ + 'qty' => 0, + ] +); +$productRepository->save($product); + +$product = $productRepository->get('simple_1020'); +$product->setStockData( + [ + 'qty' => 0, + ] +); +$productRepository->save($product); + +/** @var CategoryLinkManagementInterface $categoryLinkManagement */ +$categoryLinkManagement = $objectManager->create(CategoryLinkManagementInterface::class); +/** @var DefaultCategory $categoryHelper */ +$categoryHelper = $objectManager->get(DefaultCategory::class); + +foreach (['simple_1010', 'simple_1020', 'configurable'] as $sku) { + $categoryLinkManagement->assignProductToCategories($sku, [$categoryHelper->getId(), 333]); +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child_rollback.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child_rollback.php new file mode 100644 index 0000000000000..05b0d8959a5d3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_with_out-of-stock_child_rollback.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require __DIR__ . '/../../../Catalog/_files/category_rollback.php'; +require __DIR__ . '/product_configurable_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Element/UiComponent/ContextTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/Element/UiComponent/ContextTest.php new file mode 100644 index 0000000000000..b6c56795ebefe --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/View/Element/UiComponent/ContextTest.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\View\Element\UiComponent; + +use Magento\Framework\Api\Search\SearchCriteria; +use Magento\Framework\App\RequestInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Magento\Ui\Component\Form; +use Magento\Ui\Component\FormFactory; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; + +/** + * Test UI component context. + */ +class ContextTest extends TestCase +{ + /** + * @var RequestInterface + */ + private $request; + + /** + * @var ContextFactory + */ + private $contextFactory; + + /** + * @var FormFactory + */ + private $componentFactory; + + /** + * @inheritDoc + */ + protected function setUp() + { + $this->request = Bootstrap::getObjectManager()->get(RequestInterface::class); + $this->contextFactory = Bootstrap::getObjectManager()->get(ContextFactory::class); + $this->componentFactory = Bootstrap::getObjectManager()->get(FormFactory::class); + } + + /** + * Generate provider for the test. + * + * @return DataProviderInterface + */ + private function generateMockProvider(): DataProviderInterface + { + /** @var DataProviderInterface|MockObject $mock */ + $mock = $this->getMockForAbstractClass(DataProviderInterface::class); + $mock->method('getName')->willReturn('test'); + $mock->method('getPrimaryFieldName')->willReturn('id'); + $mock->method('getRequestFieldName')->willReturn('id'); + $mock->method('getData')->willReturn(['id' => ['some_field' => '${\'some_value\'}']]); + $mock->method('getConfigData')->willReturn([]); + $mock->method('getFieldMetaInfo')->willReturn([]); + $mock->method('getFieldSetMetaInfo')->willReturn('id'); + $mock->method('getFieldsMetaInfo')->willReturn('id'); + $mock->method('getSearchCriteria')->willReturn(new SearchCriteria()); + $mock->method('getSearchResult')->willReturn([]); + + return $mock; + } + + /** + * Check processed provider data. + * + * @return void + */ + public function testGetDataSourceData(): void + { + $dataProvider = $this->generateMockProvider(); + $context = $this->contextFactory->create(['dataProvider' => $dataProvider]); + /** @var Form $component */ + $component = $this->componentFactory->create(['context' => $context]); + $this->request->setParams(['id' => 'id']); + + $data = $context->getDataSourceData($component); + $this->assertEquals( + [ + 'test' => [ + 'type' => 'dataSource', + 'name' => 'test', + 'dataScope' => null, + 'config' => [ + 'data' => ['some_field' => '${\'some_value\'}', '__disableTmpl' => ['some_field' => true]], + 'params' => ['namespace' => null]] + ] + ], + $data + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Element/UiComponentFactoryTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/Element/UiComponentFactoryTest.php new file mode 100644 index 0000000000000..8a1064ffe6663 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/View/Element/UiComponentFactoryTest.php @@ -0,0 +1,168 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\View\Element; + +use Magento\Framework\Api\Search\SearchCriteria; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Magento\Framework\Config\DataInterface as ConfigData; +use Magento\Framework\Config\DataInterfaceFactory as ConfigDataFactory; + +/** + * Test the component factory. + */ +class UiComponentFactoryTest extends TestCase +{ + /** + * @var UiComponentFactoryFactory + */ + private $factory; + + /** + * @inheritDoc + */ + protected function setUp() + { + $this->factory = Bootstrap::getObjectManager()->get(UiComponentFactoryFactory::class); + } + + /** + * Create factory with mock config provided. + * + * @param array $mockConfig + * @return UiComponentFactory + */ + private function createFactory(array $mockConfig): UiComponentFactory + { + $dataMock = $this->getMockForAbstractClass(ConfigData::class); + $dataMock->method('get')->willReturnCallback( + function (string $id) use ($mockConfig) : array { + return $mockConfig[$id]; + } + ); + $dataFactoryMock = $this->getMockBuilder(ConfigDataFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $dataFactoryMock->method('create')->willReturn($dataMock); + + return $this->factory->create(['configFactory' => $dataFactoryMock]); + } + + /** + * Test creating a component. + * + * @return void + * @magentoAppArea adminhtml + */ + public function testCreate(): void + { + //Mocking component config. + $factory = $this->createFactory([ + 'test' => [ + 'arguments' => ['data' => ['config' => ['component' => 'uiComponent']]], + 'attributes' => [ + 'name' => 'test', + 'sorting' => true, + 'class' => 'Magento\Ui\Component\Listing', + 'component' => 'uiComponent' + ], + 'children' => [ + 'test_child' => [ + 'arguments' => [ + 'data' => ['config' => ['component' => 'uiComponent']], + 'dataProvider' => $this->generateMockProvider() + ], + 'attributes' => [ + 'name' => 'test_child', + 'sorting' => true, + 'class' => 'Magento\Ui\Component\Listing', + 'component' => 'uiComponent' + ], + 'children' => [] + ] + ] + ], + 'test_child_child' => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'component' => 'uiComponent', + 'label' => '${\'Label\'}', + 'componentType' => 'component' + ] + ], + ], + 'attributes' => [ + 'name' => 'test_child_child', + 'sorting' => true, + 'class' => 'Magento\Ui\Component\Listing', + 'component' => 'uiComponent' + ], + 'children' => [] + ] + ]); + $component = $factory->create('test', null, ['data' => ['label' => '${\'Label\'}']]); + + $componentData = $component->getData(); + //Arguments passed must be sanitized + $this->assertArrayHasKey('__disableTmpl', $componentData); + $this->assertEquals(['label' => true], $componentData['__disableTmpl']); + //Metadata provided by the dataProvider must be sanitized as well. + $this->assertArrayHasKey('test_child_child', $childData = $component->getChildComponents()); + $childData = $component->getChildComponents()['test_child_child']->getData()['config']; + $this->assertArrayHasKey('__disableTmpl', $childData); + $this->assertEquals(['label' => true], $childData['__disableTmpl']); + } + + /** + * Generate provider for the test. + * + * @return DataProviderInterface + */ + private function generateMockProvider(): DataProviderInterface + { + /** @var DataProviderInterface|MockObject $mock */ + $mock = $this->getMockForAbstractClass(DataProviderInterface::class); + $mock->method('getName')->willReturn('test'); + $mock->method('getPrimaryFieldName')->willReturn('id'); + $mock->method('getRequestFieldName')->willReturn('id'); + $mock->method('getData')->willReturn([]); + $mock->method('getConfigData')->willReturn([]); + $mock->method('getFieldMetaInfo')->willReturn([]); + $mock->method('getFieldSetMetaInfo')->willReturn('id'); + $mock->method('getFieldsMetaInfo')->willReturn('id'); + $mock->method('getSearchCriteria')->willReturn(new SearchCriteria()); + $mock->method('getSearchResult')->willReturn([]); + $mock->method('getMeta')->willReturn( + [ + 'test_child_child' => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'component' => 'uiComponent', + 'label' => '${\'Label\'}', + 'componentType' => 'component' + ] + ], + ], + 'attributes' => [ + 'name' => 'test_child_child', + 'sorting' => true, + 'class' => 'Magento\Ui\Component\Listing', + 'component' => 'uiComponent' + ] + ] + ] + ); + + return $mock; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_declared_reference.xml b/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_declared_reference.xml new file mode 100644 index 0000000000000..b99452e3345ba --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_declared_reference.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd"> + <container name="cacheable_container1-1" label="test1" htmlTag="div" htmlId="cacheable_container11" + htmlClass="class11"> + <block class="Magento\Framework\View\Element\Text" name="block-1-in-cacheable-container1"> + <action method="setText"> + <argument name="text" xsi:type="string">Test11</argument> + </action> + </block> + </container> + + <referenceContainer name="cacheable_container1-1"> + <block name="non_cacheable_block" cacheable="false"/> + </referenceContainer> +</layout> diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_missing_refference.xml b/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_missing_refference.xml new file mode 100644 index 0000000000000..2dc6ac25a71bf --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_missing_refference.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_layout.xsd"> + <container name="cacheable_container1-1" label="test1" htmlTag="div" htmlId="cacheable_container11" + htmlClass="class11"> + <block class="Magento\Framework\View\Element\Text" name="block-1-in-cacheable-container1"> + <action method="setText"> + <argument name="text" xsi:type="string">Test11</argument> + </action> + </block> + </container> + + <referenceContainer name="cacheable_container1-1-2"> + <block name="non_cacheable_block" cacheable="false"/> + </referenceContainer> +</layout> diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs.php b/dev/tests/integration/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs.php deleted file mode 100644 index 3043a5eaf2ae1..0000000000000 --- a/dev/tests/integration/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Framework\App\Config\Storage\Writer; -use Magento\Framework\App\Config\Storage\WriterInterface; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Encryption\EncryptorInterface; -use Magento\AuthorizenetAcceptjs\Gateway\Config; - -$objectManager = Bootstrap::getObjectManager(); -/** @var EncryptorInterface $encryptor */ -$encryptor = $objectManager->get(EncryptorInterface::class); - -/** @var Writer $configWriter */ -$configWriter = $objectManager->get(WriterInterface::class); -$configWriter->save('payment/' . Config::METHOD . '/active', '1'); -$configWriter->save('payment/' . Config::METHOD . '/environment', 'sandbox'); -$configWriter->save('payment/' . Config::METHOD . '/login', $encryptor->encrypt('def_login')); -$configWriter->save('payment/' . Config::METHOD . '/trans_key', $encryptor->encrypt('def_trans_key')); -$configWriter->save('payment/' . Config::METHOD . '/public_client_key', $encryptor->encrypt('def_public_client_key')); -$configWriter->save( - 'payment/' . Config::METHOD . '/trans_signature_key', - $encryptor->encrypt('def_trans_signature_key') -); - -$scopeConfig = $objectManager->get(ScopeConfigInterface::class); -$scopeConfig->clean(); diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs_rollback.php b/dev/tests/integration/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs_rollback.php deleted file mode 100644 index b73883f80f333..0000000000000 --- a/dev/tests/integration/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/_files/enable_authorizenetacceptjs_rollback.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -use Magento\Framework\App\Config\Storage\Writer; -use Magento\Framework\App\Config\Storage\WriterInterface; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\AuthorizenetAcceptjs\Gateway\Config; - -$objectManager = Bootstrap::getObjectManager(); - -/** @var Writer $configWriter */ -$configWriter = $objectManager->get(WriterInterface::class); -$configWriter->delete('payment/' . Config::METHOD . '/active'); -$configWriter->delete('payment/' . Config::METHOD . '/environment'); -$configWriter->delete('payment/' . Config::METHOD . '/login'); -$configWriter->delete('payment/' . Config::METHOD . '/trans_key'); -$configWriter->delete('payment/' . Config::METHOD . '/public_client_key'); -$configWriter->delete('payment/' . Config::METHOD . '/trans_signature_key'); - -$scopeConfig = $objectManager->get(ScopeConfigInterface::class); -$scopeConfig->clean(); diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php b/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php index ff2a2835448c6..1af8d900b23dc 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods.php @@ -9,7 +9,6 @@ * @magentoConfigFixture default_store payment/cashondelivery/active 1 * @magentoConfigFixture default_store payment/checkmo/active 1 * @magentoConfigFixture default_store payment/purchaseorder/active 1 - * @magentoConfigFixture default_store payment/authorizenet_acceptjs/active 1 */ declare(strict_types=1); @@ -26,7 +25,6 @@ $configWriter->save('payment/cashondelivery/active', 1); $configWriter->save('payment/checkmo/active', 1); $configWriter->save('payment/purchaseorder/active', 1); -$configWriter->save('payment/authorizenet_acceptjs/active', 1); $scopeConfig = $objectManager->get(ScopeConfigInterface::class); $scopeConfig->clean(); diff --git a/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods_rollback.php b/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods_rollback.php index 3be528eb41de8..b3268ecc9ee98 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods_rollback.php +++ b/dev/tests/integration/testsuite/Magento/GraphQl/Quote/_files/enable_offline_payment_methods_rollback.php @@ -20,4 +20,3 @@ $configWriter->delete('payment/cashondelivery/active'); $configWriter->delete('payment/checkmo/active'); $configWriter->delete('payment/purchaseorder/active'); -$configWriter->delete('payment/authorizenet_acceptjs/active'); diff --git a/dev/tests/integration/testsuite/Magento/Integration/_files/customer_with_integration_token.php b/dev/tests/integration/testsuite/Magento/Integration/_files/customer_with_integration_token.php new file mode 100644 index 0000000000000..68b9a72759d3f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Integration/_files/customer_with_integration_token.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Integration\Api\CustomerTokenServiceInterface; + +require __DIR__ . '/../../../Magento/Customer/_files/customer.php'; + +/** @var CustomerTokenServiceInterface $customerTokenService */ +$customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + +$customerTokenService->createCustomerAccessToken($customer->getEmail(), $customer->getPassword()); diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_auth_only_rollback.php b/dev/tests/integration/testsuite/Magento/Integration/_files/customer_with_integration_token_rollback.php similarity index 62% rename from dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_auth_only_rollback.php rename to dev/tests/integration/testsuite/Magento/Integration/_files/customer_with_integration_token_rollback.php index 5a65a1fc0d0c7..768b6f25cb747 100644 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetAcceptjs/Fixture/order_auth_only_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Integration/_files/customer_with_integration_token_rollback.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); -require __DIR__ . '/order_captured_rollback.php'; +require __DIR__ . '/../../../Magento/Customer/_files/customer_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Category/DecimalFilterTest.php b/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Category/DecimalFilterTest.php index f84cd5ba08259..53425bd42fbd9 100644 --- a/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Category/DecimalFilterTest.php +++ b/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Category/DecimalFilterTest.php @@ -82,7 +82,10 @@ public function getFiltersWithCustomAttributeDataProvider(): array 'attribute_data' => ['is_filterable' => 0], 'expectation' => [], ], - 'used_in_navigation_with_results' => [ + + /* @TODO: Should be uncommented in MC-16650 */ + + /*'used_in_navigation_with_results' => [ 'products_data' => [ 'simple1000' => 10.00, 'simple1001' => 20.00, @@ -100,7 +103,7 @@ public function getFiltersWithCustomAttributeDataProvider(): array 'count' => 1, ], ], - ], + ],*/ ]; } } diff --git a/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Search/DecimalFilterTest.php b/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Search/DecimalFilterTest.php index a4d8a64add4b7..325bf1a3d50dc 100644 --- a/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Search/DecimalFilterTest.php +++ b/dev/tests/integration/testsuite/Magento/LayeredNavigation/Block/Navigation/Search/DecimalFilterTest.php @@ -50,12 +50,15 @@ public function getFiltersWithCustomAttributeDataProvider(): array 'not_used_in_navigation' => [ 'attribute_data' => ['is_filterable' => 0, 'is_filterable_in_search' => 0], ], - 'used_in_navigation_with_results' => [ + + /* @TODO: Should be uncommented in MC-16650 */ + + /*'used_in_navigation_with_results' => [ 'attribute_data' => [ 'is_filterable' => AbstractFilter::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS, 'is_filterable_in_search' => 1, ], - ], + ],*/ ] ); diff --git a/dev/tests/integration/testsuite/Magento/MediaContent/Model/ExtractAssetsFromContentTest.php b/dev/tests/integration/testsuite/Magento/MediaContent/Model/ExtractAssetsFromContentTest.php new file mode 100644 index 0000000000000..841113d35c1d2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaContent/Model/ExtractAssetsFromContentTest.php @@ -0,0 +1,98 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\MediaContentApi\Api\ExtractAssetsFromContentInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test for ExtractAssetsFromContent + */ +class ExtractAssetsFromContentTest extends TestCase +{ + /** + * @var ExtractAssetsFromContentInterface + */ + private $extractAssetsFromContent; + + /** + * @inheritdoc + */ + public function setUp(): void + { + $this->extractAssetsFromContent = Bootstrap::getObjectManager() + ->get(ExtractAssetsFromContentInterface::class); + } + + /** + * Assing assets to content, retrieve the data, then unassign assets from content + * + * @magentoDataFixture Magento/MediaGallery/_files/media_asset.php + * + * @dataProvider contentProvider + * @param string $content + * @param array $assetIds + */ + public function testExecute(string $content, array $assetIds): void + { + $assets = $this->extractAssetsFromContent->execute($content); + + $extractedAssetIds = []; + foreach ($assets as $asset) { + $extractedAssetIds[] = $asset->getId(); + } + + sort($assetIds); + sort($extractedAssetIds); + + $this->assertEquals($assetIds, $extractedAssetIds); + } + + /** + * Data provider for testExecute + * + * @return array + */ + public function contentProvider() + { + return [ + 'Empty Content' => [ + '', + [] + ], + 'No paths in content' => [ + 'content without paths', + [] + ], + 'Relevant paths in content' => [ + 'content {{media url="testDirectory/path.jpg"}} content', + [ + 2020 + ] + ], + 'Relevant wysiwyg paths in content' => [ + 'content <img src="https://domain.com/media/testDirectory/path.jpg"}} content', + [ + 2020 + ] + ], + 'Relevant path content' => [ + '/media/testDirectory/path.jpg', + [ + 2020 + ] + ], + 'Irrelevant paths in content' => [ + 'content {{media url="media/non-existing-path.png"}} content', + [] + ], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaContent/Model/SaveDeleteContentAssetLinksTest.php b/dev/tests/integration/testsuite/Magento/MediaContent/Model/SaveDeleteContentAssetLinksTest.php new file mode 100644 index 0000000000000..4244cd66475a0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaContent/Model/SaveDeleteContentAssetLinksTest.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\MediaContentApi\Api\SaveContentAssetLinksInterface; +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; +use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface; +use Magento\MediaContentApi\Api\GetAssetIdsByContentIdentityInterface; +use Magento\MediaContentApi\Api\GetContentByAssetIdsInterface; +use Magento\MediaContentApi\Api\DeleteContentAssetLinksInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test for AssignAssets service + */ +class SaveDeleteContentAssetLinksTest extends TestCase +{ + /** + * @var SaveContentAssetLinksInterface + */ + private $saveContentAssetLinks; + + /** + * @var GetAssetIdsByContentIdentityInterface + */ + private $getAssetIdsByContentIdentity; + + /** + * @var GetContentByAssetIdsInterface + */ + private $getContentByAssetIds; + + /** + * @var DeleteContentAssetLinksInterface + */ + private $deleteContentAssetLinks; + + /** + * @inheritdoc + */ + public function setUp(): void + { + $this->saveContentAssetLinks = Bootstrap::getObjectManager()->get(SaveContentAssetLinksInterface::class); + $this->getAssetIdsByContentIdentity = Bootstrap::getObjectManager() + ->get(GetAssetIdsByContentIdentityInterface::class); + $this->getContentByAssetIds = Bootstrap::getObjectManager()->get(GetContentByAssetIdsInterface::class); + $this->deleteContentAssetLinks = Bootstrap::getObjectManager()->get(DeleteContentAssetLinksInterface::class); + } + + /** + * Save asset to content links, retrieve the data, delete assets to content links + */ + public function testAssignRetrieveAndUnassign(): void + { + $entityType = 'catalog_product'; + $entityId = 42; + $field = 'description'; + $assetIds = [56, 78]; + + $contentIdentity = Bootstrap::getObjectManager()->create( + ContentIdentityInterface::class, + [ + 'entityType' => $entityType, + 'entityId' => $entityId, + 'field' => $field + ] + ); + + $contentAssetLinks = []; + + foreach ($assetIds as $assetId) { + $contentAssetLinks[] = Bootstrap::getObjectManager()->create( + ContentAssetLinkInterface::class, + [ + 'assetId' => $assetId, + 'contentIdentity' => $contentIdentity + ] + ); + } + + $this->saveContentAssetLinks->execute($contentAssetLinks); + $retrievedAssetIds = $this->getAssetIdsByContentIdentity->execute($contentIdentity); + $this->assertEquals($assetIds, $retrievedAssetIds); + $retrievedContentIdentities = $this->getContentByAssetIds->execute($assetIds); + $this->assertEquals(count($retrievedContentIdentities), 1); + + foreach ($retrievedContentIdentities as $identity) { + $this->assertEquals($entityType, $identity->getEntityType()); + $this->assertEquals($entityId, $identity->getEntityId()); + $this->assertEquals($field, $identity->getField()); + } + + $this->deleteContentAssetLinks->execute($contentAssetLinks); + + $this->assertEmpty($this->getContentByAssetIds->execute($assetIds)); + $this->assertEmpty($this->getAssetIdsByContentIdentity->execute($contentIdentity)); + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaContent/Model/UpdateContentAssetLinksTest.php b/dev/tests/integration/testsuite/Magento/MediaContent/Model/UpdateContentAssetLinksTest.php new file mode 100644 index 0000000000000..0a9393c1c3c20 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaContent/Model/UpdateContentAssetLinksTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ +declare(strict_types=1); + +namespace Magento\MediaContent\Model; + +use Magento\MediaContentApi\Api\Data\ContentIdentityInterface; +use Magento\MediaContentApi\Api\GetAssetIdsByContentIdentityInterface; +use Magento\MediaContentApi\Api\UpdateContentAssetLinksInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test for UpdateContentAssetLinks + */ +class UpdateContentAssetLinksTest extends TestCase +{ + /** + * @var UpdateContentAssetLinksInterface + */ + private $updateContentAssetLinks; + + /** + * @var GetAssetIdsByContentIdentityInterface + */ + private $getAssetIdsByContentIdentity; + + /** + * @inheritdoc + */ + public function setUp(): void + { + $this->updateContentAssetLinks = Bootstrap::getObjectManager()->get(UpdateContentAssetLinksInterface::class); + $this->getAssetIdsByContentIdentity = Bootstrap::getObjectManager() + ->get(GetAssetIdsByContentIdentityInterface::class); + } + + /** + * Assing assets to content, retrieve the data, then unassign assets from content + * + * @magentoDataFixture Magento/MediaGallery/_files/media_asset.php + */ + public function testExecute(): void + { + $entityType = 'catalog_product'; + $entityId = 2020; + $field = 'description'; + $contentWithoutAsset = ''; + $contentWithAsset = 'content {{media url="testDirectory/path.jpg"}} content'; + + $contentIdentity = Bootstrap::getObjectManager()->create( + ContentIdentityInterface::class, + [ + 'entityType' => $entityType, + 'entityId' => $entityId, + 'field' => $field + ] + ); + + $this->updateContentAssetLinks->execute($contentIdentity, $contentWithoutAsset); + $this->assertEmpty($this->getAssetIdsByContentIdentity->execute($contentIdentity)); + + $this->updateContentAssetLinks->execute($contentIdentity, $contentWithAsset); + $this->assertNotEmpty($this->getAssetIdsByContentIdentity->execute($contentIdentity)); + + $this->updateContentAssetLinks->execute($contentIdentity, $contentWithoutAsset); + $this->assertEmpty($this->getAssetIdsByContentIdentity->execute($contentIdentity)); + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/AssetEndToEndTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/AssetEndToEndTest.php new file mode 100644 index 0000000000000..61b3c22c3ca54 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/AssetEndToEndTest.php @@ -0,0 +1,151 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model; + +use Magento\MediaGalleryApi\Api\Data\KeywordInterfaceFactory; +use Magento\MediaGalleryApi\Api\Data\AssetInterfaceFactory; +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterfaceFactory; +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface; +use Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface; +use Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface; +use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface; +use Magento\MediaGalleryApi\Api\SaveAssetsInterface; +use Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface; +use Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * End to end test for working with assets and keywords + */ +class AssetEndToEndTest extends TestCase +{ + /** + * @var GetAssetsKeywordsInterface + */ + private $saveAssetsKeywords; + + /** + * @var GetAssetsKeywordsInterface + */ + private $getAssetsKeywords; + + /** + * @var AssetKeywordsInterfaceFactory + */ + private $assetsKeywordsFactory; + + /** + * @var AssetInterfaceFactory + */ + private $assetFactory; + + /** + * @var KeywordInterfaceFactory + */ + private $keywordFactory; + + /** + * @var SaveAssetsInterface + */ + private $saveAssets; + + /** + * @var GetAssetsByIdsInterface + */ + private $getAssetsByIds; + + /** + * @var GetAssetsByPathsInterface + */ + private $getAssetsByPath; + + /** + * @var DeleteAssetsByPathsInterface + */ + private $deleteAssetsByPaths; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->saveAssetsKeywords = Bootstrap::getObjectManager()->get(SaveAssetsKeywordsInterface::class); + $this->getAssetsKeywords = Bootstrap::getObjectManager()->get(GetAssetsKeywordsInterface::class); + $this->assetsKeywordsFactory = Bootstrap::getObjectManager()->get(AssetKeywordsInterfaceFactory::class); + $this->assetFactory = Bootstrap::getObjectManager()->get(AssetInterfaceFactory::class); + $this->keywordFactory = Bootstrap::getObjectManager()->get(KeywordInterfaceFactory::class); + $this->saveAssets = Bootstrap::getObjectManager()->get(SaveAssetsInterface::class); + $this->getAssetsByIds = Bootstrap::getObjectManager()->get(GetAssetsByIdsInterface::class); + $this->getAssetsByPath = Bootstrap::getObjectManager()->get(GetAssetsByPathsInterface::class); + $this->deleteAssetsByPaths = Bootstrap::getObjectManager()->get(DeleteAssetsByPathsInterface::class); + } + + /** + * Testing assets keywords save and get + */ + public function testExecute(): void + { + $keyword1 = $this->keywordFactory->create( + [ + 'keyword' => 'pear' + ] + ); + + $keyword2 = $this->keywordFactory->create( + [ + 'keyword' => 'plum' + ] + ); + + $asset = $this->assetFactory->create( + [ + 'path' => 'fruit.jpg', + 'title' => 'Img', + 'source' => 'Local', + 'contentType' => 'image/jpeg', + 'width' => 420, + 'height' => 240, + 'size' => 12877 + ] + ); + $this->saveAssets->execute([$asset]); + $loadedAssets = $this->getAssetsByPath->execute([$asset->getPath()]); + $loadedAsset = $loadedAssets[0]; + + $this->assertEquals(1, count($loadedAssets)); + + $assetKeywords = $this->assetsKeywordsFactory->create( + [ + 'assetId' => $loadedAsset->getId(), + 'keywords' => [ + $keyword1, + $keyword2 + ] + ] + ); + + $this->saveAssetsKeywords->execute([$assetKeywords]); + $loadedAssetKeywords = $this->getAssetsKeywords->execute([$loadedAsset->getId()]); + + $this->assertEquals(1, count($loadedAssetKeywords)); + + /** @var AssetKeywordsInterface $loadedAssetKeywords1 */ + $loadedAssetKeywords1 = current($loadedAssetKeywords); + + $loadedKeywords = $loadedAssetKeywords1->getKeywords(); + + $this->assertEquals(2, count($loadedKeywords)); + + foreach ($loadedKeywords as $theKeyword) { + $this->assertTrue(in_array($theKeyword->getKeyword(), ['pear', 'plum'])); + } + + $this->deleteAssetsByPaths->execute(['fruit.jpg']); + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/Directory/Command/CreateByPathsTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/Directory/Command/CreateByPathsTest.php new file mode 100644 index 0000000000000..3511cdec532fa --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/Directory/Command/CreateByPathsTest.php @@ -0,0 +1,110 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory\Command; + +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem; +use Magento\MediaGalleryApi\Api\CreateDirectoriesByPathsInterface; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Test for CreateDirectoriesByPathsInterface + */ +class CreateByPathsTest extends \PHPUnit\Framework\TestCase +{ + /** + * Test directory name + */ + private const TEST_DIRECTORY_NAME = 'testCreateDirectory'; + + /** + * Absolute path to the media directory + */ + private $mediaDirectoryPath; + + /** + * @var CreateDirectoriesByPathsInterface + */ + private $createByPaths; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->createByPaths = Bootstrap::getObjectManager()->get(CreateDirectoriesByPathsInterface::class); + $this->mediaDirectoryPath = Bootstrap::getObjectManager()->get(Filesystem::class) + ->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath(); + } + + /** + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function testCreateDirectory(): void + { + $this->createByPaths->execute([self::TEST_DIRECTORY_NAME]); + $this->assertFileExists($this->mediaDirectoryPath . self::TEST_DIRECTORY_NAME); + } + + /** + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + */ + public function testCreateDirectoryThatAlreadyExist(): void + { + $this->createByPaths->execute([self::TEST_DIRECTORY_NAME]); + $this->assertFileExists($this->mediaDirectoryPath . self::TEST_DIRECTORY_NAME); + $this->createByPaths->execute([self::TEST_DIRECTORY_NAME]); + } + + /** + * @param array $paths + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @expectedException \Magento\Framework\Exception\CouldNotSaveException + * @dataProvider notAllowedPathsProvider + */ + public function testCreateDirectoryWithRelativePath(array $paths): void + { + $this->createByPaths->execute($paths); + } + + /** + * Provider of paths that are not allowed for deletion + * + * @return array + */ + public function notAllowedPathsProvider(): array + { + return [ + [ + ['../../pub/' . self::TEST_DIRECTORY_NAME] + ], + [ + ['theme/' . self::TEST_DIRECTORY_NAME] + ], + [ + ['../../pub/media', 'theme'] + ] + ]; + } + + /** + * @throws \Magento\Framework\Exception\FileSystemException + */ + public static function tearDownAfterClass() + { + $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class); + /** @var \Magento\Framework\Filesystem\Directory\WriteInterface $directory */ + $directory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); + if ($directory->isExist(self::TEST_DIRECTORY_NAME)) { + $directory->delete(self::TEST_DIRECTORY_NAME); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/Directory/Command/DeleteByPathsTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/Directory/Command/DeleteByPathsTest.php new file mode 100644 index 0000000000000..3eaf7fbe3538a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/Directory/Command/DeleteByPathsTest.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + * + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\Directory\Command; + +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem; +use Magento\MediaGalleryApi\Api\DeleteDirectoriesByPathsInterface; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Test for DeleteDirectoriesByPathsInterface + */ +class DeleteByPathsTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var DeleteDirectoriesByPathsInterface + */ + private $deleteByPaths; + + /** + * @var string + */ + private $testDirectoryName = 'testDeleteDirectory'; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->deleteByPaths = Bootstrap::getObjectManager()->get(DeleteDirectoriesByPathsInterface::class); + $this->filesystem = Bootstrap::getObjectManager()->get(Filesystem::class); + } + + /** + * @throws \Magento\Framework\Exception\CouldNotDeleteException + * @throws \Magento\Framework\Exception\FileSystemException + */ + public function testDeleteDirectory(): void + { + /** @var \Magento\Framework\Filesystem\Directory\WriteInterface $mediaDirectory */ + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory->create($this->testDirectoryName); + $fullPath = $mediaDirectory->getAbsolutePath($this->testDirectoryName); + $this->assertFileExists($fullPath); + $this->deleteByPaths->execute([$this->testDirectoryName]); + $this->assertFileNotExists($fullPath); + } + + /** + * @param array $paths + * @throws \Magento\Framework\Exception\CouldNotDeleteException + * @expectedException \Magento\Framework\Exception\CouldNotDeleteException + * @dataProvider notAllowedPathsProvider + */ + public function testDeleteDirectoryThatIsNotAllowed(array $paths): void + { + $this->deleteByPaths->execute($paths); + } + + /** + * Provider of paths that are not allowed for deletion + * + * @return array + */ + public function notAllowedPathsProvider(): array + { + return [ + [ + ['../../pub/media'] + ], + [ + ['theme'] + ], + [ + ['../../pub/media', 'theme'] + ] + ]; + } + + /** + * @throws \Magento\Framework\Exception\FileSystemException + */ + public function tearDown() + { + $directory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + if ($directory->isExist($this->testDirectoryName)) { + $directory->delete($this->testDirectoryName); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/IsBlacklistedTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/IsBlacklistedTest.php new file mode 100644 index 0000000000000..47ff2b3a94aa3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/IsBlacklistedTest.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model; + +use Magento\MediaGalleryApi\Api\IsPathBlacklistedInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test for IsPathBlacklistedInterface + */ +class IsBlacklistedTest extends TestCase +{ + + /** + * @var IsPathBlacklistedInterface + */ + private $service; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->service = Bootstrap::getObjectManager()->get(IsPathBlacklistedInterface::class); + } + + /** + * Testing the blacklisted paths + * + * @param string $path + * @param bool $isBlacklisted + * @dataProvider pathsProvider + */ + public function testExecute(string $path, bool $isBlacklisted): void + { + $this->assertEquals($isBlacklisted, $this->service->execute($path)); + } + + /** + * Provider of paths and if the path should be in the blacklist + * + * @return array + */ + public function pathsProvider(): array + { + return [ + ['theme', true], + ['.thumbs', true], + ['catalog/product/somedir', true], + ['catalog/category', false] + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetKeywordsTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetKeywordsTest.php new file mode 100644 index 0000000000000..f6b9ed5e1ff75 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetKeywordsTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Behat\Gherkin\Keywords\KeywordsInterface; +use Magento\MediaGalleryApi\Api\Data\KeywordInterfaceFactory; +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterfaceFactory; +use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface; +use Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface; +use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface; +use Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Testing assets keywords operation + */ +class AssetKeywordsTest extends TestCase +{ + private const FIXTURE_ASSET_PATH = 'testDirectory/path.jpg'; + + /** + * @var GetAssetsKeywordsInterface + */ + private $saveAssetsKeywords; + + /** + * @var GetAssetsKeywordsInterface + */ + private $getAssetsKeywords; + + /** + * @var AssetKeywordsInterfaceFactory + */ + private $assetsKeywordsFactory; + + /** + * @var KeywordInterfaceFactory + */ + private $keywordFactory; + + /** + * @var GetAssetsByPathsInterface + */ + private $getAssetsByPath; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->saveAssetsKeywords = Bootstrap::getObjectManager()->get(SaveAssetsKeywordsInterface::class); + $this->getAssetsKeywords = Bootstrap::getObjectManager()->get(GetAssetsKeywordsInterface::class); + $this->assetsKeywordsFactory = Bootstrap::getObjectManager()->get(AssetKeywordsInterfaceFactory::class); + $this->keywordFactory = Bootstrap::getObjectManager()->get(KeywordInterfaceFactory::class); + $this->getAssetsByPath = Bootstrap::getObjectManager()->get(GetAssetsByPathsInterface::class); + } + + /** + * Testing assets keywords save and get + * + * @magentoDataFixture Magento/MediaGallery/_files/media_asset.php + * @dataProvider keywordsProvider + * @param array $keywords + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testSaveAndGetKeywords(array $keywords): void + { + $keywords = ['pear', 'plum']; + + $loadedAssets = $this->getAssetsByPath->execute([self::FIXTURE_ASSET_PATH]); + $this->assertEquals(1, count($loadedAssets)); + $loadedAsset = current($loadedAssets); + + $assetKeywords = $this->assetsKeywordsFactory->create( + [ + 'assetId' => $loadedAsset->getId(), + 'keywords' => $this->getKeywords($keywords) + ] + ); + + $this->saveAssetsKeywords->execute([$assetKeywords]); + $loadedAssetKeywords = $this->getAssetsKeywords->execute([$loadedAsset->getId()]); + + $this->assertEquals(1, count($loadedAssetKeywords)); + + /** @var AssetKeywordsInterface $loadedAssetKeyword */ + $loadedAssetKeyword = current($loadedAssetKeywords); + + $loadedKeywords = $loadedAssetKeyword->getKeywords(); + + $this->assertEquals(count($keywords), count($loadedKeywords)); + + $loadedKeywordStrings = []; + foreach ($loadedKeywords as $loadedKeywordObject) { + $loadedKeywordStrings[] = $loadedKeywordObject->getKeyword(); + } + + sort($loadedKeywordStrings); + sort($keywords); + + $this->assertEquals($keywords, $loadedKeywordStrings); + } + + /** + * Data provider of paths matching existing asset + * + * @return array + */ + public function keywordsProvider(): array + { + return [ + [['one-keyword']], + [['кириллица']], + [['plum', 'pear']], + [[]] + ]; + } + + /** + * Create keywords + * + * @param string[] $keywords + * @return KeywordsInterface[] + */ + private function getKeywords(array $keywords): array + { + $keywordObjects = []; + foreach ($keywords as $keyword) { + $keywordObjects[] = $this->keywordFactory->create( + [ + 'keyword' => $keyword + ] + ); + } + return $keywordObjects; + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetsByIdsTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetsByIdsTest.php new file mode 100644 index 0000000000000..de0393372d23d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetsByIdsTest.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test for GetAssetsByIdsInterface + */ +class AssetsByIdsTest extends TestCase +{ + private const FIXTURE_ASSET_ID = 2020; + private const FIXTURE_ASSET_PATH = 'testDirectory/path.jpg'; + + /** + * @var GetAssetsByIdsInterface + */ + private $getAssetsByIds; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->getAssetsByIds = Bootstrap::getObjectManager()->get(GetAssetsByIdsInterface::class); + } + + /** + * Testing assets keywords save and get + * + * @throws \Magento\Framework\Exception\LocalizedException + * + * @magentoDataFixture Magento/MediaGallery/_files/media_asset.php + */ + public function testExecute(): void + { + $assets = $this->getAssetsByIds->execute([self::FIXTURE_ASSET_ID]); + $this->assertEquals(1, count($assets)); + $this->assertEquals($assets[0]->getPath(), self::FIXTURE_ASSET_PATH); + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetsTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetsTest.php new file mode 100644 index 0000000000000..8aec9454951f9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetsTest.php @@ -0,0 +1,188 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Magento\Framework\Reflection\DataObjectProcessor; +use Magento\MediaGalleryApi\Api\Data\AssetInterfaceFactory; +use Magento\MediaGalleryApi\Api\Data\AssetInterface; +use Magento\MediaGalleryApi\Api\GetAssetsByIdsInterface; +use Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface; +use Magento\MediaGalleryApi\Api\SaveAssetsInterface; +use Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test for assets operations + */ +class AssetsTest extends TestCase +{ + /** + * @var AssetInterfaceFactory + */ + private $assetFactory; + + /** + * @var SaveAssetsInterface + */ + private $saveAssets; + + /** + * @var GetAssetsByIdsInterface + */ + private $getAssetsByIds; + + /** + * @var GetAssetsByPathsInterface + */ + private $getAssetsByPath; + + /** + * @var DeleteAssetsByPathsInterface + */ + private $deleteAssetsByPaths; + + /** + * @var DataObjectProcessor + */ + private $dataObjectProcessor; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->assetFactory = Bootstrap::getObjectManager()->get(AssetInterfaceFactory::class); + $this->saveAssets = Bootstrap::getObjectManager()->get(SaveAssetsInterface::class); + $this->getAssetsByIds = Bootstrap::getObjectManager()->get(GetAssetsByIdsInterface::class); + $this->getAssetsByPath = Bootstrap::getObjectManager()->get(GetAssetsByPathsInterface::class); + $this->deleteAssetsByPaths = Bootstrap::getObjectManager()->get(DeleteAssetsByPathsInterface::class); + $this->dataObjectProcessor = Bootstrap::getObjectManager()->get(DataObjectProcessor::class); + } + + /** + * Testing assets keywords save and get + * + * @param array $assetsData + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\LocalizedException + * + * @dataProvider assetsDataProvider + */ + public function testExecute(array $assetsData): void + { + $this->saveAssets->execute($this->getAssets($assetsData)); + + $paths = $this->getKeyValues($assetsData, 'path'); + $loadedAssets = $this->getAssetsByPath->execute($paths); + $loadedPaths = $this->getFieldValues($loadedAssets, 'path'); + + $this->assertEquals(count($assetsData), count($loadedAssets)); + + sort($paths); + sort($loadedPaths); + $this->assertEquals($paths, $loadedPaths); + + $this->deleteAssetsByPaths->execute($paths); + $this->assertEmpty($this->getAssetsByPath->execute($paths)); + } + + /** + * Data provider for testExecute + * + * @return array + */ + public function assetsDataProvider(): array + { + return [ + 'One asset' => [ + 'assetsData' => [ + 'asset1' => [ + 'path' => 'fruit.jpg', + 'title' => 'Img', + 'source' => 'Local', + 'contentType' => 'image/jpeg', + 'width' => 420, + 'height' => 240, + 'size' => 12877 + ] + ] + ], + 'Two assets' => [ + 'assetsData' => [ + 'asset1' => [ + 'path' => 'image.jpg', + 'title' => 'Img', + 'source' => 'Local', + 'contentType' => 'image/jpeg', + 'width' => 420, + 'height' => 240, + 'size' => 12877 + ], + 'asset2' => [ + 'path' => 'image2.jpg', + 'title' => 'Img', + 'source' => 'Local', + 'contentType' => 'image/jpeg', + 'width' => 420, + 'height' => 240, + 'size' => 12877 + ] + ] + ], + ]; + } + + /** + * Create assets + * + * @param array $assetsData + * @return AssetInterface[] + */ + private function getAssets(array $assetsData): array + { + $assets = []; + foreach ($assetsData as $assetData) { + $assets[] = $this->assetFactory->create($assetData); + } + return $assets; + } + + /** + * Get field values from assets + * + * @param AssetInterface[] $assets + * @param string $fieldName + * @return string[] + */ + private function getFieldValues(array $assets, string $fieldName): array + { + $values = []; + foreach ($assets as $asset) { + $data = $this->dataObjectProcessor->buildOutputDataArray($asset, AssetInterface::class); + $values[] = $data[$fieldName]; + } + return $values; + } + + /** + * Get key values from assets data array + * + * @param array $assetsData + * @param string $key + * @return string[] + */ + private function getKeyValues(array $assetsData, string $key): array + { + $values = []; + foreach ($assetsData as $assetData) { + $values[] = $assetData[$key]; + } + return $values; + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/DeleteAssetsTest.php b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/DeleteAssetsTest.php new file mode 100644 index 0000000000000..0b790730805e9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/DeleteAssetsTest.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\MediaGallery\Model\ResourceModel; + +use Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface; +use Magento\MediaGalleryApi\Api\DeleteAssetsByPathsInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Testing delete assets operation + */ +class DeleteAssetsTest extends TestCase +{ + private const FIXTURE_ASSET_PATH = 'testDirectory/path.jpg'; + /** + * @var GetAssetsByPathsInterface + */ + private $getAssetsByPath; + + /** + * @var DeleteAssetsByPathsInterface + */ + private $deleteAssetsByPaths; + + /** + * @inheritdoc + */ + public function setUp() + { + $this->getAssetsByPath = Bootstrap::getObjectManager()->get(GetAssetsByPathsInterface::class); + $this->deleteAssetsByPaths = Bootstrap::getObjectManager()->get(DeleteAssetsByPathsInterface::class); + } + + /** + * Test deletion of assets by path + * + * @magentoDataFixture Magento/MediaGallery/_files/media_asset.php + * + * @param array $paths + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\LocalizedException + * + * @dataProvider matchingPathsProvider + */ + public function testAssetsAreDeleted(array $paths): void + { + $this->deleteAssetsByPaths->execute($paths); + $this->assertEmpty($this->getAssetsByPath->execute([self::FIXTURE_ASSET_PATH])); + } + + /** + * Test scenarios where delete operation should not delete an asset + * + * @magentoDataFixture Magento/MediaGallery/_files/media_asset.php + * + * @param array $paths + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\LocalizedException + * + * @dataProvider notMatchingPathsProvider + */ + public function testAssetsAreNotDeleted(array $paths): void + { + $this->deleteAssetsByPaths->execute($paths); + $this->assertNotEmpty($this->getAssetsByPath->execute([self::FIXTURE_ASSET_PATH])); + } + + /** + * Data provider of paths matching existing asset + * + * @return array + */ + public function matchingPathsProvider(): array + { + return [ + [['testDirectory/path.jpg']], + [['testDirectory/']], + [['testDirectory']] + ]; + } + + /** + * Data provider of paths not matching existing asset + * + * @return array + */ + public function notMatchingPathsProvider(): array + { + return [ + [['testDirectory/path.png']], + [['anotherDirectory/path.jpg']], + [['path.jpg']] + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/_files/media_asset.php b/dev/tests/integration/testsuite/Magento/MediaGallery/_files/media_asset.php new file mode 100644 index 0000000000000..0a2a00c254975 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/_files/media_asset.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\MediaGalleryApi\Api\Data\AssetInterface; +use Magento\MediaGalleryApi\Api\Data\AssetInterfaceFactory; +use Magento\MediaGalleryApi\Model\Asset\Command\SaveInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); +/** @var AssetInterfaceFactory $mediaAssetFactory */ +$mediaAssetFactory = $objectManager->get(AssetInterfaceFactory::class); +/** @var AssetInterface $mediaAsset */ +$mediaAsset = $mediaAssetFactory->create( + [ + 'id' => 2020, + 'path' => 'testDirectory/path.jpg', + 'contentType' => 'image', + 'title' => 'Img', + 'source' => 'Local', + 'width' => 420, + 'height' => 240, + 'size' => 12877 + ] +); +/** @var SaveInterface $mediaSave */ +$mediaSave = $objectManager->get(SaveInterface::class); +$mediaId = $mediaSave->execute($mediaAsset); diff --git a/dev/tests/integration/testsuite/Magento/MediaGallery/_files/media_asset_rollback.php b/dev/tests/integration/testsuite/Magento/MediaGallery/_files/media_asset_rollback.php new file mode 100644 index 0000000000000..76756e912b3b5 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/MediaGallery/_files/media_asset_rollback.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\MediaGalleryApi\Model\Asset\Command\DeleteByPathInterface; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var DeleteByPathInterface $mediaSave */ +$mediaAssetDelete = $objectManager->get(DeleteByPathInterface::class); + +try { + $mediaAssetDelete->execute('testDirectory/path.jpg'); +} catch (\Exception $exception) { + +} diff --git a/dev/tests/integration/testsuite/Magento/PageCache/Model/Layout/DepersonalizePluginTest.php b/dev/tests/integration/testsuite/Magento/PageCache/Model/Layout/DepersonalizePluginTest.php new file mode 100644 index 0000000000000..96cd5c009d6c3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/PageCache/Model/Layout/DepersonalizePluginTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\PageCache\Model\Layout; + +use Magento\Framework\App\Cache\Type\Layout as LayoutCache; +use Magento\Framework\Message\Session; +use Magento\Framework\View\Layout; +use Magento\Framework\View\LayoutFactory; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Integration tests for \Magento\PageCache\Model\Layout\DepersonalizePlugin class. + * + * @magentoAppArea frontend + */ +class DepersonalizePluginTest extends TestCase +{ + /** + * @var Session + */ + private $messageSession; + + /** + * @var Layout + */ + private $layout; + + /** + * @var LayoutCache + */ + private $cache; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->messageSession = Bootstrap::getObjectManager()->get(Session::class); + $this->layout = Bootstrap::getObjectManager()->get(LayoutFactory::class)->create(); + $this->cache = Bootstrap::getObjectManager()->get(LayoutCache::class); + } + + /** + * @inheritDoc + */ + protected function tearDown() + { + $this->messageSession->clearStorage(); + } + + /** + * @magentoCache full_page enabled + * @dataProvider afterGenerateElementsDataProvider + * + * @param string $layout + * @param array $expectedResult + * @return void + */ + public function testAfterGenerateElements(string $layout, array $expectedResult): void + { + $this->cache->clean(); + $this->assertTrue($this->layout->loadFile($layout)); + $this->messageSession->setData(['some_data' => 1]); + $this->layout->generateElements(); + $this->assertEquals($expectedResult, $this->messageSession->getData()); + } + + /** + * @return array + */ + public function afterGenerateElementsDataProvider(): array + { + return [ + 'cacheable' => [ + 'layout' => INTEGRATION_TESTS_DIR . '/testsuite/Magento/Framework/View/_files/layout/cacheable.xml', + 'expectedResult' => [], + ], + 'nonCacheable' => [ + 'layout' => INTEGRATION_TESTS_DIR . '/testsuite/Magento/Framework/View/_files/layout/non_cacheable.xml', + 'expectedResult' => ['some_data' => 1], + ], + 'nonCacheableBlockWithoutReference' => [ + 'layout' => INTEGRATION_TESTS_DIR + . '/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_missing_refference.xml', + 'expectedResult' => [], + ], + 'nonCacheableBlockWithExistedReference' => [ + 'layout' => INTEGRATION_TESTS_DIR + . '/testsuite/Magento/Framework/View/_files/layout/non_cacheable_block_with_declared_reference.xml', + 'expectedResult' => ['some_data' => 1], + ], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php index c080d7a3ab229..6b2806f147dea 100644 --- a/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php @@ -295,6 +295,8 @@ private function executeTestFlow($flatRateAmount, $tableRateAmount) */ public function testEstimateByAddressWithInclExclTaxAndVATGroup() { + $this->markTestSkipped('MC-33463'); + /** @var CustomerRepositoryInterface $customerRepository */ $customerRepository = $this->objectManager->get(CustomerRepositoryInterface::class); $customer = $customerRepository->get('customer@example.com'); diff --git a/dev/tests/integration/testsuite/Magento/Review/Block/Adminhtml/Edit/Tab/ReviewsTest.php b/dev/tests/integration/testsuite/Magento/Review/Block/Adminhtml/Edit/Tab/ReviewsTest.php new file mode 100644 index 0000000000000..0b9fbe9428b5a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Review/Block/Adminhtml/Edit/Tab/ReviewsTest.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Review\Block\Adminhtml\Edit\Tab; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Checks customer products reviews tab + * + * @see \Magento\Review\Block\Adminhtml\Edit\Tab\Reviews + * @magentoAppArea adminhtml + */ +class ReviewsTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Reviews */ + private $block; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(Reviews::class); + } + + /** + * @magentoDataFixture Magento/Review/_files/customer_review.php + * + * @return void + */ + public function testReviewGrid(): void + { + $this->block->setCustomerId(1); + $this->assertCount(1, $this->block->getPreparedCollection()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Review/Controller/Adminhtml/Customer/ProductReviewsTest.php b/dev/tests/integration/testsuite/Magento/Review/Controller/Adminhtml/Customer/ProductReviewsTest.php index 4203fb9c16b29..961e029dfc38b 100644 --- a/dev/tests/integration/testsuite/Magento/Review/Controller/Adminhtml/Customer/ProductReviewsTest.php +++ b/dev/tests/integration/testsuite/Magento/Review/Controller/Adminhtml/Customer/ProductReviewsTest.php @@ -8,13 +8,30 @@ namespace Magento\Review\Controller\Adminhtml\Customer; use Magento\Framework\App\Request\Http; +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\View\LayoutInterface; use Magento\TestFramework\TestCase\AbstractBackendController; /** * Test for customer product reviews page. + * + * @magentoAppArea adminhtml */ class ProductReviewsTest extends AbstractBackendController { + /** @var LayoutInterface */ + private $layout; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->layout = $this->_objectManager->get(LayoutInterface::class); + } + /** * Check Customer product review action. * @@ -23,9 +40,36 @@ class ProductReviewsTest extends AbstractBackendController */ public function testProductReviewsAction(): void { - $this->getRequest()->setPostValue(['id' => 1])->setMethod(Http::METHOD_POST); + $this->dispatchWithIdParam(1); + $this->assertContains('<div id="reviewGrid"', $this->getResponse()->getBody()); + } + + /** + * @return void + */ + public function testProductReviews(): void + { + $customerId = 1; + $this->dispatchWithIdParam($customerId); + $block = $this->layout->getBlock('admin.customer.reviews'); + $this->assertNotFalse($block); + $this->assertEquals( + $customerId, + $block->getCustomerId(), + 'Block customer id value does not match expected value' + ); + } + + /** + * Dispatch request with id parameter + * + * @param int $id + * @return void + */ + private function dispatchWithIdParam(int $id): void + { + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setParams(['id' => $id]); $this->dispatch('backend/review/customer/productReviews'); - $body = $this->getResponse()->getBody(); - $this->assertContains('<div id="reviewGrid"', $body); } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Creditmemo/ItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Creditmemo/ItemsTest.php index f130c788a65db..318a07127767d 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Creditmemo/ItemsTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Creditmemo/ItemsTest.php @@ -3,74 +3,249 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Block\Order\Creditmemo; -class ItemsTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Registry; +use Magento\Framework\View\Element\Text; +use Magento\Framework\View\LayoutInterface; +use Magento\Framework\View\Result\PageFactory; +use Magento\Sales\Api\Data\CreditmemoInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Tests for view creditmemo items block. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ItemsTest extends TestCase { - /** - * @var \Magento\Framework\View\LayoutInterface - */ - protected $_layout; + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var LayoutInterface */ + private $layout; + + /** @var Items */ + private $block; + + /** @var CreditmemoInterface */ + private $creditmemo; + + /** @var Registry */ + private $registry; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** @var PageFactory */ + private $pageFactory; /** - * @var \Magento\Sales\Block\Order\Creditmemo\Items + * @inheritdoc */ - protected $_block; + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->layout = $this->objectManager->get(LayoutInterface::class); + $this->block = $this->layout->createBlock(Items::class, 'block'); + $this->creditmemo = $this->objectManager->get(CreditmemoInterface::class); + $this->registry = $this->objectManager->get(Registry::class); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + $this->pageFactory = $this->objectManager->get(PageFactory::class); + } /** - * @var \Magento\Sales\Model\Order\Creditmemo + * @inheritdoc */ - protected $_creditmemo; - - protected function setUp() + protected function tearDown() { - $this->_layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\View\LayoutInterface::class - ); - $this->_block = $this->_layout->createBlock(\Magento\Sales\Block\Order\Creditmemo\Items::class, 'block'); - $this->_creditmemo = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Sales\Model\Order\Creditmemo::class - ); + $this->registry->unregister('current_order'); + + parent::tearDown(); } /** * @magentoAppIsolation enabled + * + * @return void */ - public function testGetTotalsHtml() + public function testGetTotalsHtml(): void { - $childBlock = $this->_layout->addBlock( - \Magento\Framework\View\Element\Text::class, + $childBlock = $this->layout->addBlock( + Text::class, 'creditmemo_totals', 'block' ); - $expectedHtml = '<b>Any html</b>'; $this->assertEmpty($childBlock->getCreditmemo()); - $this->assertNotEquals($expectedHtml, $this->_block->getTotalsHtml($this->_creditmemo)); - + $this->assertNotEquals($expectedHtml, $this->block->getTotalsHtml($this->creditmemo)); $childBlock->setText($expectedHtml); - $actualHtml = $this->_block->getTotalsHtml($this->_creditmemo); - $this->assertSame($this->_creditmemo, $childBlock->getCreditmemo()); + $actualHtml = $this->block->getTotalsHtml($this->creditmemo); + $this->assertSame($this->creditmemo, $childBlock->getCreditmemo()); $this->assertEquals($expectedHtml, $actualHtml); } - public function testGetCommentsHtml() + /** + * @magentoAppIsolation enabled + * + * @return void + */ + public function testGetCommentsHtml(): void { - $childBlock = $this->_layout->addBlock( - \Magento\Framework\View\Element\Text::class, + $childBlock = $this->layout->addBlock( + Text::class, 'creditmemo_comments', 'block' ); - $expectedHtml = '<b>Any html</b>'; $this->assertEmpty($childBlock->getEntity()); $this->assertEmpty($childBlock->getTitle()); - $this->assertNotEquals($expectedHtml, $this->_block->getCommentsHtml($this->_creditmemo)); - + $this->assertNotEquals($expectedHtml, $this->block->getCommentsHtml($this->creditmemo)); $childBlock->setText($expectedHtml); - $actualHtml = $this->_block->getCommentsHtml($this->_creditmemo); - $this->assertSame($this->_creditmemo, $childBlock->getEntity()); + $actualHtml = $this->block->getCommentsHtml($this->creditmemo); + $this->assertSame($this->creditmemo, $childBlock->getEntity()); $this->assertNotEmpty($childBlock->getTitle()); $this->assertEquals($expectedHtml, $actualHtml); } + + /** + * @magentoDataFixture Magento/Sales/_files/refunds_for_items.php + * + * @return void + */ + public function testDisplayingCreditmemos(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $this->registerOrder($order); + $blockHtml = $this->renderCreditmemoItemsBlock(); + $this->assertCreditmemosBlock($order, $blockHtml); + } + + /** + * Assert creditmemos block. + * + * @param OrderInterface $order + * @param string $blockHtml + * @return void + */ + private function assertCreditmemosBlock(OrderInterface $order, string $blockHtml): void + { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//a[contains(@href, 'sales/order/printCreditmemo/order_id/%s')]/span[contains(text(), '%s')]", + $order->getId(), + __('Print All Refunds') + ), + $blockHtml + ), + sprintf('%s button was not found.', __('Print All Refunds')) + ); + $this->assertNotCount(0, $order->getCreditmemosCollection(), 'Creditmemos collection is empty'); + foreach ($order->getCreditmemosCollection() as $creditmemo) { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//div[contains(@class, 'order-title')]/strong[contains(text(), '%s')]", + __('Refund #') . $creditmemo->getIncrementId() + ), + $blockHtml + ), + sprintf('Title for %s was not found.', __('Refund #') . $creditmemo->getIncrementId()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//a[contains(@href, 'sales/order/printCreditmemo/creditmemo_id/%s')]" + . "/span[contains(text(), '%s')]", + $creditmemo->getId(), + __('Print Refund') + ), + $blockHtml + ), + sprintf('%s button for #%s was not found.', __('Print Refund'), $creditmemo->getIncrementId()) + ); + $this->assertCreditmemoItems($creditmemo, $blockHtml); + } + } + + /** + * Assert creditmemo items list. + * + * @param CreditmemoInterface $creditmemo + * @param string $html + * @return void + */ + private function assertCreditmemoItems(CreditmemoInterface $creditmemo, string $html): void + { + $this->assertNotCount(0, $creditmemo->getItemsCollection(), 'Creditmemo items collection is empty'); + $fieldsToCheck = [ + 'name' => "/td[contains(@class, 'name')]/strong[contains(text(), '%s')]", + 'sku' => "/td[contains(@class, 'sku') and contains(text(), '%s')]", + 'price' => "/td[contains(@class, 'price')]//span[contains(text(), '%01.2f')]", + 'qty' => "/td[contains(@class, 'qty') and contains(text(), '%d')]", + 'row_total' => "/td[contains(@class, 'subtotal')]//span[contains(text(), '%01.2f')]", + 'discount_amount' => "/td[contains(@class, 'discount')]/span[contains(text(), '%01.2f')]", + ]; + foreach ($creditmemo->getItemsCollection() as $item) { + $rowXpath = sprintf( + "//table[@id='my-refund-table-%s']//tr[@id='order-item-row-%s']", + $creditmemo->getId(), + $item->getId() + ); + foreach ($fieldsToCheck as $key => $xpath) { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($rowXpath . $xpath, $item->getData($key)), $html), + sprintf('Item %s wasn\'t found or not equals to %s.', $key, $item->getData($key)) + ); + } + } + } + + /** + * Render creditmemo items block. + * + * @return string + */ + private function renderCreditmemoItemsBlock(): string + { + $page = $this->pageFactory->create(); + $page->addHandle([ + 'default', + 'sales_order_creditmemo', + ]); + $page->getLayout()->generateXml(); + $creditmemoItemsBlock = $page->getLayout()->getBlock('creditmemo_items')->unsetChild('creditmemo_totals'); + $creditmemoItemsBlock->getRequest()->setRouteName('sales')->setControllerName('order') + ->setActionName('creditmemo'); + + return $creditmemoItemsBlock->toHtml(); + } + + /** + * Register order in registry. + * + * @param OrderInterface $order + * @return void + */ + private function registerOrder(OrderInterface $order): void + { + $this->registry->unregister('current_order'); + $this->registry->register('current_order', $order); + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Creditmemo/TotalsTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Creditmemo/TotalsTest.php new file mode 100644 index 0000000000000..a88b2d3a5f0df --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Creditmemo/TotalsTest.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Block\Order\Creditmemo; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Tests for view creditmemo totals block. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class TotalsTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Totals */ + private $block; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(Totals::class) + ->setTemplate('Magento_Sales::order/totals.phtml'); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/refunds_for_items.php + * + * @return void + */ + public function testCreditmemoTotalsBlock(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $creditmemo = $order->getCreditmemosCollection()->getFirstItem(); + $this->assertNotNull($creditmemo->getId()); + $blockHtml = $this->block->setOrder($order)->setCreditmemo($creditmemo)->toHtml(); + $message = '"%s" for creditmemo wasn\'t found or not equals to %01.2f'; + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//th[contains(text(), '%s')]/following-sibling::td/span[contains(text(), '%01.2f')]", + __('Subtotal'), + $creditmemo->getSubtotal() + ), + $blockHtml + ), + sprintf($message, __('Subtotal'), $creditmemo->getSubtotal()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//th[contains(text(), '%s')]/following-sibling::td/span[contains(text(), '%01.2f')]", + __('Shipping & Handling'), + $creditmemo->getShippingAmount() + ), + $blockHtml + ), + sprintf($message, __('Shipping & Handling'), $creditmemo->getShippingAmount()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//tr[contains(@class, 'grand_total') and contains(.//strong, '%s')]" + . "//span[contains(text(), '%01.2f')]", + __('Grand Total'), + $creditmemo->getGrandTotal() + ), + $blockHtml + ), + sprintf($message, __('Grand Total'), $creditmemo->getGrandTotal()) + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/HistoryTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/HistoryTest.php new file mode 100644 index 0000000000000..d7e342c096dc9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/HistoryTest.php @@ -0,0 +1,177 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Block\Order; + +use Magento\Customer\Model\Session; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Tests for customer order grid. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class HistoryTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Session */ + private $customerSession; + + /** @var History */ + private $block; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->customerSession = $this->objectManager->get(Session::class); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(History::class); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->customerSession->logout(); + + parent::tearDown(); + } + + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + * + * @return void + */ + public function testCustomerOrderGridWithoutOrders(): void + { + $this->customerSession->loginById(1); + $this->assertContains((string)$this->block->getEmptyOrdersMessage(), strip_tags($this->block->toHtml())); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_with_customer.php + * + * @return void + */ + public function testCustomerOrderGridWithOrder(): void + { + $this->customerSession->loginById(1); + $this->assertCustomerOrderGrid(['100000001'], $this->block->toHtml()); + } + + /** + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Sales/_files/orders_with_customer.php + * + * @return void + */ + public function testCustomerOrderGridWithSomeOrders(): void + { + $this->customerSession->loginById(1); + $ordersToCheck = ['100000002', '100000003', '100000004', '100000005', '100000006']; + $this->assertCustomerOrderGrid($ordersToCheck, $this->block->toHtml()); + } + + /** + * Assert customer order grid. + * + * @param array $ordersToCheck + * @param string $blockHtml + * @return void + */ + private function assertCustomerOrderGrid(array $ordersToCheck, string $blockHtml): void + { + foreach ($ordersToCheck as $orderIncrementId) { + $order = $this->orderFactory->create()->loadByIncrementId($orderIncrementId); + $rowXpath = sprintf("//td[contains(@class,'id') and contains(text(), '%s')]", $order->getRealOrderId()); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + $rowXpath . "/following-sibling::td[contains(@class, 'date') and contains(text(), '%s')]", + $this->block->formatDate($order->getCreatedAt()) + ), + $blockHtml + ), + sprintf('Created date for order #%s wasn\'t found in row.', $orderIncrementId) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + $rowXpath . "/following-sibling::td[contains(@class, 'total')]/span[contains(text(), '%s')]", + $order->getTotal() + ), + $blockHtml + ), + sprintf( + 'Order Totals for order #%s wasn\'t found or not equal to "%s" in row.', + $orderIncrementId, + $order->getTotal() + ) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + $rowXpath . "/following-sibling::td[contains(@class, 'status') and contains(text(), '%s')]", + $order->getStatusLabel() + ), + $blockHtml + ), + sprintf( + 'Order status for order #%s wasn\'t found or not equal to "%s" in row.', + $orderIncrementId, + $order->getStatusLabel() + ) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + $rowXpath . "/following-sibling::td/a[contains(@href, 'sales/order/view/order_id/%s')]" + . "/span[contains(text(), '%s')]", + $order->getId(), + __('View Order') + ), + $blockHtml + ), + sprintf('View order button for order #%s wasn\'t found.', $orderIncrementId) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + $rowXpath . "/following-sibling::td/a[contains(@data-post," + . "'sales\/order\/reorder\/order_id\/%s')]/span[contains(text(), '%s')]", + $order->getId(), + __('Reorder') + ), + $blockHtml + ), + sprintf('Reorder button for order #%s wasn\'t found.', $orderIncrementId) + ); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Info/ButtonsTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Info/ButtonsTest.php new file mode 100644 index 0000000000000..676415629fdc9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Info/ButtonsTest.php @@ -0,0 +1,115 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Block\Order\Info; + +use Magento\Customer\Model\Session; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Registry; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Test for order action buttons. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class ButtonsTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Registry */ + private $registry; + + /** @var Session */ + private $customerSession; + + /** @var OrderInterface */ + private $order; + + /** @var Buttons */ + private $block; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->registry = $this->objectManager->get(Registry::class); + $this->customerSession = $this->objectManager->get(Session::class); + $this->order = $this->objectManager->get(OrderInterface::class); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(Buttons::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->registry->unregister('current_order'); + $this->customerSession->logout(); + + parent::tearDown(); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_with_customer.php + * + * @return void + */ + public function testDisplayingOrderActionButtons(): void + { + $this->customerSession->loginById(1); + $order = $this->order->loadByIncrementId('100000001'); + $this->registerOrder($order); + $blockHtml = $this->block->toHtml(); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//a[contains(@data-post, 'sales\/order\/reorder\/order_id\/%s')]/span[contains(text(), '%s')]", + $order->getId(), + __('Reorder') + ), + $blockHtml + ), + sprintf('%s button wasn\'t found.', __('Reorder')) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//a[contains(@href, 'sales/order/print/order_id/%s')]/span[contains(text(), '%s')]", + $order->getId(), + __('Print Order') + ), + $blockHtml + ), + sprintf('%s button wasn\'t found.', __('Print Order')) + ); + } + + /** + * Register order in registry. + * + * @param OrderInterface $order + * @return void + */ + private function registerOrder(OrderInterface $order): void + { + $this->registry->unregister('current_order'); + $this->registry->register('current_order', $order); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/InfoTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/InfoTest.php new file mode 100644 index 0000000000000..1b84db76869e3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/InfoTest.php @@ -0,0 +1,172 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Block\Order; + +use Magento\Directory\Model\CountryFactory; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Registry; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderAddressInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Tests for order info block. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class InfoTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Registry */ + private $registry; + + /** @var LayoutInterface */ + private $layout; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** @var CountryFactory */ + private $countryFactory; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->registry = $this->objectManager->get(Registry::class); + $this->layout = $this->objectManager->get(LayoutInterface::class); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + $this->countryFactory = $this->objectManager->get(CountryFactory::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->registry->unregister('current_order'); + + parent::tearDown(); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_with_customer.php + * + * @return void + */ + public function testOrderStatus(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $this->registerOrder($order); + $block = $this->layout->createBlock(Info::class)->setTemplate('Magento_Sales::order/order_status.phtml'); + $this->assertContains((string)__($order->getStatusLabel()), strip_tags($block->toHtml())); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_with_customer.php + * + * @return void + */ + public function testOrderDate(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $this->registerOrder($order); + $block = $this->layout->createBlock(Info::class)->setTemplate('Magento_Sales::order/order_date.phtml'); + $this->assertContains( + (string)__('Order Date: %1', $block->formatDate($order->getCreatedAt(), \IntlDateFormatter::LONG)), + strip_tags($block->toHtml()) + ); + } + + /** + * @magentoDataFixture Magento/Sales/_files/customer_order_with_two_items.php + * + * @return void + */ + public function testOrderInformation(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $this->registerOrder($order); + $blockHtml = $this->layout->createBlock(Info::class)->toHtml(); + $this->assertOrderAddress($order->getShippingAddress(), $blockHtml); + $this->assertOrderAddress($order->getBillingAddress(), $blockHtml); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//div[contains(@class, 'box-order-shipping-method') and contains(.//span, '%s')]" + . "//div[contains(text(), '%s')]", + __('Shipping Method'), + $order->getShippingDescription() + ), + $blockHtml + ), + 'Shipping method for order wasn\'t found.' + ); + } + + /** + * Assert order address. + * + * @param OrderAddressInterface $address + * @param string $html + * @return void + */ + private function assertOrderAddress(OrderAddressInterface $address, string $html): void + { + $addressBoxXpath = sprintf("//div[contains(@class, 'box-order-%s-address')]", $address->getAddressType()) + . "//address[contains(., '%s')]"; + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($addressBoxXpath, $address->getName()), $html), + sprintf('Customer name for %s address wasn\'t found.', $address->getAddressType()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + $addressBoxXpath, + $this->countryFactory->create()->loadByCode($address->getData('country_id'))->getName() + ), + $html + ), + sprintf('Country for %s address wasn\'t found.', $address->getAddressType()) + ); + $attributes = ['company', 'street', 'city', 'region', 'postcode', 'telephone']; + foreach ($attributes as $key) { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($addressBoxXpath, $address->getData($key)), $html), + sprintf('%s for %s address wasn\'t found.', $key, $address->getAddressType()) + ); + } + } + + /** + * Register order in registry. + * + * @param OrderInterface $order + * @return void + */ + private function registerOrder(OrderInterface $order): void + { + $this->registry->unregister('current_order'); + $this->registry->register('current_order', $order); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Invoice/ItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Invoice/ItemsTest.php index cfb97ee4298ec..bf13d5a296eee 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Invoice/ItemsTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Invoice/ItemsTest.php @@ -3,70 +3,243 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Block\Order\Invoice; -class ItemsTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Registry; +use Magento\Framework\View\Element\Text; +use Magento\Framework\View\LayoutInterface; +use Magento\Framework\View\Result\PageFactory; +use Magento\Sales\Api\Data\InvoiceInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\Sales\Api\Data\InvoiceInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Tests for view invoice items block. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ItemsTest extends TestCase { - /** - * @var \Magento\Framework\View\LayoutInterface - */ - protected $_layout; + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Registry */ + private $registry; + + /** @var LayoutInterface */ + private $layout; + + /** @var Items */ + private $block; + + /** @var InvoiceInterfaceFactory */ + private $invoiceFactory; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** @var PageFactory */ + private $pageFactory; /** - * @var \Magento\Sales\Block\Order\Invoice\Items + * @inheritdoc */ - protected $_block; + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->registry = $this->objectManager->get(Registry::class); + $this->layout = $this->objectManager->get(LayoutInterface::class); + $this->block = $this->layout->createBlock(Items::class, 'block'); + $this->invoiceFactory = $this->objectManager->get(InvoiceInterfaceFactory::class); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + $this->pageFactory = $this->objectManager->get(PageFactory::class); + } /** - * @var \Magento\Sales\Model\Order\Invoice + * @inheritdoc */ - protected $_invoice; - - protected function setUp() + protected function tearDown() { - $this->_layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\View\LayoutInterface::class - ); - $this->_block = $this->_layout->createBlock(\Magento\Sales\Block\Order\Invoice\Items::class, 'block'); - $this->_invoice = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Sales\Model\Order\Invoice::class - ); + $this->registry->unregister('current_order'); + + parent::tearDown(); } /** * @magentoAppIsolation enabled + * + * @return void */ - public function testGetInvoiceTotalsHtml() + public function testGetInvoiceTotalsHtml(): void { - $childBlock = $this->_layout->addBlock(\Magento\Framework\View\Element\Text::class, 'invoice_totals', 'block'); - + $childBlock = $this->layout->addBlock(Text::class, 'invoice_totals', 'block'); $expectedHtml = '<b>Any html</b>'; $this->assertEmpty($childBlock->getInvoice()); - $this->assertNotEquals($expectedHtml, $this->_block->getInvoiceTotalsHtml($this->_invoice)); - + $invoice = $this->invoiceFactory->create(); + $this->assertNotEquals($expectedHtml, $this->block->getInvoiceTotalsHtml($invoice)); $childBlock->setText($expectedHtml); - $actualHtml = $this->_block->getInvoiceTotalsHtml($this->_invoice); - $this->assertSame($this->_invoice, $childBlock->getInvoice()); + $actualHtml = $this->block->getInvoiceTotalsHtml($invoice); + $this->assertSame($invoice, $childBlock->getInvoice()); $this->assertEquals($expectedHtml, $actualHtml); } - public function testGetInvoiceCommentsHtml() + /** + * @magentoAppIsolation enabled + * + * @return void + */ + public function testGetInvoiceCommentsHtml(): void { - $childBlock = $this->_layout->addBlock( - \Magento\Framework\View\Element\Text::class, + $childBlock = $this->layout->addBlock( + Text::class, 'invoice_comments', 'block' ); - $expectedHtml = '<b>Any html</b>'; $this->assertEmpty($childBlock->getEntity()); $this->assertEmpty($childBlock->getTitle()); - $this->assertNotEquals($expectedHtml, $this->_block->getInvoiceCommentsHtml($this->_invoice)); - + $invoice = $this->invoiceFactory->create(); + $this->assertNotEquals($expectedHtml, $this->block->getInvoiceCommentsHtml($invoice)); $childBlock->setText($expectedHtml); - $actualHtml = $this->_block->getInvoiceCommentsHtml($this->_invoice); - $this->assertSame($this->_invoice, $childBlock->getEntity()); + $actualHtml = $this->block->getInvoiceCommentsHtml($invoice); + $this->assertSame($invoice, $childBlock->getEntity()); $this->assertNotEmpty($childBlock->getTitle()); $this->assertEquals($expectedHtml, $actualHtml); } + + /** + * @magentoDataFixture Magento/Sales/_files/invoices_for_items.php + * + * @return void + */ + public function testDisplayingInvoices(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $this->registerOrder($order); + $blockHtml = $this->renderInvoiceItemsBlock(); + $this->assertInvoicesBlock($order, $blockHtml); + } + + /** + * Assert invoices block. + * + * @param OrderInterface $order + * @param string $blockHtml + * @return void + */ + private function assertInvoicesBlock(OrderInterface $order, string $blockHtml): void + { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//a[contains(@href, 'sales/order/printInvoice/order_id/%s')]/span[contains(text(), '%s')]", + $order->getId(), + __('Print All Invoices') + ), + $blockHtml + ), + sprintf('%s button was not found.', __('Print All Invoices')) + ); + $this->assertNotCount(0, $order->getInvoiceCollection(), 'Invoice collection is empty'); + foreach ($order->getInvoiceCollection() as $invoice) { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//div[contains(@class, 'order-title')]/strong[contains(text(), '%s')]", + __('Invoice #') . $invoice->getIncrementId() + ), + $blockHtml + ), + sprintf('Title for %s was not found.', __('Invoice #') . $invoice->getIncrementId()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//a[contains(@href, 'sales/order/printInvoice/invoice_id/%s')]/span[contains(text(), '%s')]", + $invoice->getId(), + __('Print Invoice') + ), + $blockHtml + ), + sprintf('%s button for #%s was not found.', __('Print Invoice'), $invoice->getIncrementId()) + ); + $this->assertInvoiceItems($invoice, $blockHtml); + } + } + + /** + * Assert invoice items list. + * + * @param InvoiceInterface $invoice + * @param string $blockHtml + * @return void + */ + private function assertInvoiceItems(InvoiceInterface $invoice, string $blockHtml): void + { + $this->assertNotCount(0, $invoice->getItemsCollection(), 'Invoice items collection is empty'); + $fieldsToCheck = [ + 'name' => "/td[contains(@class, 'name')]/strong[contains(text(), '%s')]", + 'sku' => "/td[contains(@class, 'sku') and contains(text(), '%s')]", + 'price' => "/td[contains(@class, 'price')]//span[contains(text(), '%01.2f')]", + 'qty' => "/td[contains(@class, 'qty')]/span[contains(text(), '%d')]", + 'row_total' => "/td[contains(@class, 'subtotal')]//span[contains(text(), '%01.2f')]", + ]; + foreach ($invoice->getItemsCollection() as $item) { + $itemRowXpath = sprintf( + "//table[@id='my-invoice-table-%s']//tr[@id='order-item-row-%s']", + $invoice->getId(), + $item->getId() + ); + foreach ($fieldsToCheck as $key => $xpath) { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($itemRowXpath . $xpath, $item->getData($key)), $blockHtml), + sprintf('Item %s wasn\'t found or not equals to %s.', $key, $item->getData($key)) + ); + } + } + } + + /** + * Render invoice items block. + * + * @return string + */ + private function renderInvoiceItemsBlock(): string + { + $page = $this->pageFactory->create(); + $page->addHandle([ + 'default', + 'sales_order_invoice', + ]); + $page->getLayout()->generateXml(); + $invoiceItemsBlock = $page->getLayout()->getBlock('invoice_items')->unsetChild('invoice_totals'); + $invoiceItemsBlock->getRequest()->setRouteName('sales')->setControllerName('order')->setActionName('invoice'); + + return $invoiceItemsBlock->toHtml(); + } + + /** + * Register order in registry. + * + * @param OrderInterface $order + * @return void + */ + private function registerOrder(OrderInterface $order): void + { + $this->registry->unregister('current_order'); + $this->registry->register('current_order', $order); + } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Invoice/TotalsTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Invoice/TotalsTest.php new file mode 100644 index 0000000000000..1fe7e02833a2f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Invoice/TotalsTest.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Block\Order\Invoice; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Tests for view invoice totals block. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class TotalsTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Totals */ + private $block; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->objectManager = Bootstrap::getObjectManager(); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(Totals::class) + ->setTemplate('Magento_Sales::order/totals.phtml'); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/invoices_for_items.php + * + * @return void + */ + public function testInvoiceTotalsBlock(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $invoice = $order->getInvoiceCollection()->getFirstItem(); + $this->assertNotNull($invoice->getId()); + $blockHtml = $this->block->setOrder($order)->setInvoice($invoice)->toHtml(); + $message = '"%s" for invoice wasn\'t found or not equals to %01.2f'; + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//th[contains(text(), '%s')]/following-sibling::td/span[contains(text(), '%01.2f')]", + __('Subtotal'), + $invoice->getSubtotal() + ), + $blockHtml + ), + sprintf($message, __('Subtotal'), $invoice->getSubtotal()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//th[contains(text(), '%s')]/following-sibling::td/span[contains(text(), '%01.2f')]", + __('Shipping & Handling'), + $invoice->getShippingAmount() + ), + $blockHtml + ), + sprintf($message, __('Shipping & Handling'), $invoice->getShippingAmount()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//tr[contains(@class, 'grand_total') and contains(.//strong, '%s')]" + . "//span[contains(text(), '%01.2f')]", + __('Grand Total'), + $invoice->getGrandTotal() + ), + $blockHtml + ), + sprintf($message, __('Grand Total'), $invoice->getGrandTotal()) + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Item/Renderer/DefaultRendererTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Item/Renderer/DefaultRendererTest.php new file mode 100644 index 0000000000000..147efc2cd6c78 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/Item/Renderer/DefaultRendererTest.php @@ -0,0 +1,111 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Block\Order\Item\Renderer; + +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + +/** + * Tests for default renderer order items. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + */ +class DefaultRendererTest extends TestCase +{ + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var DefaultRenderer */ + private $block; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->block = $this->objectManager->get(LayoutInterface::class)->createBlock(DefaultRenderer::class); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/shipment_for_order_with_customer.php + * + * @return void + */ + public function testDisplayingShipmentItem(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $shipment = $order->getShipmentsCollection()->getFirstItem(); + $this->assertNotNull($shipment->getId()); + $item = $shipment->getAllItems()[0] ?? null; + $this->assertNotNull($item); + $blockHtml = $this->block->setTemplate('Magento_Sales::order/shipment/items/renderer/default.phtml') + ->setItem($item)->toHtml(); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//td[contains(@class, 'name')]/strong[contains(text(), '%s')]", + $item->getName() + ), + $blockHtml + ), + sprintf('Item with name %s wasn\'t found.', $item->getName()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//td[contains(@class, 'sku') and contains(text(), '%s')]", + $item->getSku() + ), + $blockHtml + ), + sprintf('Item with sku %s wasn\'t found.', $item->getSku()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//td[contains(@class, 'qty') and contains(text(), '%d')]", + $item->getQty() + ), + $blockHtml + ), + sprintf( + 'Qty for item %s wasn\'t found or not equals to %s.', + $item->getName(), + $item->getQty() + ) + ); + } + + /** + * @magentoDataFixture Magento/Sales/_files/refunds_for_items.php + * + * @return void + */ + public function testCreditmemoItemTotalAmount(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $creditmemo = $order->getCreditmemosCollection()->getFirstItem(); + $this->assertNotNull($creditmemo->getId()); + $item = $creditmemo->getItemsCollection()->getFirstItem(); + $this->assertNotNull($item->getId()); + $this->assertEquals(10.00, $this->block->getTotalAmount($item)); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/ItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/ItemsTest.php index 4c7b202fc1351..cb211b343cf0d 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/ItemsTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/ItemsTest.php @@ -3,133 +3,228 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Sales\Block\Order; -class ItemsTest extends \PHPUnit\Framework\TestCase +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Registry; +use Magento\Framework\View\LayoutInterface; +use Magento\Framework\View\Result\PageFactory; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\Sales\Model\ResourceModel\Order\Item\Collection; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use Magento\Theme\Block\Html\Pager; +use PHPUnit\Framework\TestCase; + +/** + * Tests order items block. + * + * @magentoAppArea frontend + * @magentoDbIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ItemsTest extends TestCase { - /** - * @var \Magento\Sales\Block\Order\Items - */ - private $model; + /** @var Items */ + private $block; - /** - * @var \Magento\Framework\View\LayoutInterface - */ + /** @var LayoutInterface */ private $layout; - /** - * @var \Magento\Framework\ObjectManagerInterface - */ + /** @var ObjectManagerInterface */ private $objectManager; - /** - * @var \Magento\Framework\Registry - */ + /** @var Registry */ private $registry; + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** @var PageFactory */ + private $pageFactory; + + /** + * @inheritdoc + */ protected function setUp() { - $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->layout = $this->objectManager->get(\Magento\Framework\View\LayoutInterface::class); - $this->registry = $this->objectManager->get(\Magento\Framework\Registry::class); + $this->objectManager = Bootstrap::getObjectManager(); + $this->layout = $this->objectManager->get(LayoutInterface::class); + $this->registry = $this->objectManager->get(Registry::class); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + $this->pageFactory = $this->objectManager->get(PageFactory::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->registry->unregister('current_order'); + + parent::tearDown(); } /** * @magentoDataFixture Magento/Sales/_files/order.php + * + * @return void */ - public function testGetOrderItems() + public function testGetOrderItems(): void { - $this->registerOrder(); - $this->model = $this->layout->createBlock(\Magento\Sales\Block\Order\Items::class); - $this->assertTrue(count($this->model->getItems()) > 0); + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $this->registerOrder($order); + $this->block = $this->layout->createBlock(Items::class); + $this->assertCount(1, $this->block->getItems()); } /** - * @magentoAppIsolation enabled * @magentoConfigFixture default/sales/orders/items_per_page 3 * @magentoDataFixture Magento/Sales/_files/order_item_list.php + * + * @return void */ - public function testPagerIsDisplayed() + public function testPagerIsDisplayed(): void { - $this->registerOrder(); - - /** @var \Magento\Sales\Block\Order\Items model */ - $this->model = $this->layout->createBlock(\Magento\Sales\Block\Order\Items::class, 'items_block'); + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $this->registerOrder($order); + $this->block = $this->layout->createBlock(Items::class, 'items_block'); $this->layout->addBlock( - $this->objectManager->get(\Magento\Theme\Block\Html\Pager::class), + $this->objectManager->get(Pager::class), 'sales_order_item_pager', 'items_block' ); - $this->model->setLayout($this->layout); - - $this->assertTrue($this->model->isPagerDisplayed()); + $this->block->setLayout($this->layout); + $this->assertTrue($this->block->isPagerDisplayed()); } /** * @magentoDataFixture Magento/Sales/_files/order_item_list.php + * + * @return void */ - public function testPagerIsNotDisplayed() + public function testPagerIsNotDisplayed(): void { - $this->registerOrder(); - - /** @var \Magento\Sales\Block\Order\Items model */ - $this->model = $this->layout->createBlock(\Magento\Sales\Block\Order\Items::class, 'items_block'); + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $this->registerOrder($order); + $this->block = $this->layout->createBlock(Items::class, 'items_block'); $this->layout->addBlock( - $this->objectManager->get(\Magento\Theme\Block\Html\Pager::class), + $this->objectManager->get(Pager::class), 'sales_order_item_pager', 'items_block' ); - $this->model->setLayout($this->layout); - - $this->assertFalse($this->model->isPagerDisplayed()); + $this->block->setLayout($this->layout); + $this->assertFalse($this->block->isPagerDisplayed()); + $this->assertEmpty(preg_replace('/\s+/', '', strip_tags($this->block->getPagerHtml()))); } /** - * @magentoAppIsolation enabled - * @magentoAppArea frontend * @magentoConfigFixture default/sales/orders/items_per_page 3 * @magentoDataFixture Magento/Sales/_files/order_item_list.php + * + * @return void */ - public function testGetPagerHtml() + public function testGetPagerHtml(): void { - $this->registerOrder(); - - /** @var \Magento\Sales\Block\Order\Items model */ - $this->model = $this->layout->createBlock(\Magento\Sales\Block\Order\Items::class, 'items_block'); + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $this->registerOrder($order); + $this->block = $this->layout->createBlock(Items::class, 'items_block'); $this->layout->addBlock( - $this->objectManager->get(\Magento\Theme\Block\Html\Pager::class), + $this->objectManager->get(Pager::class), 'sales_order_item_pager', 'items_block' ); - $this->model->setLayout($this->layout); - - $this->assertNotEmpty($this->model->getPagerHtml()); + $this->block->setLayout($this->layout); + $this->assertNotEmpty(preg_replace('/\s+/', '', strip_tags($this->block->getPagerHtml()))); + $this->assertTrue($this->block->isPagerDisplayed()); } /** * @magentoDataFixture Magento/Sales/_files/order.php + * + * @return void + */ + public function testGetOrder(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000001'); + $this->registerOrder($order); + $this->block = $this->layout->createBlock(Items::class, 'items_block'); + $this->assertEquals($order, $this->block->getOrder()); + } + + /** + * @magentoDataFixture Magento/Sales/_files/customer_order_with_two_items.php + * + * @return void + */ + public function testDisplayingOrderItems(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $this->registerOrder($order); + $blockHtml = $this->renderOrderItemsBlock(); + $this->assertOrderItems($order->getItemsCollection(), $blockHtml); + } + + /** + * Render order items block. + * + * @return string */ - public function testGetOrder() + private function renderOrderItemsBlock(): string { - $order = $this->registerOrder(); + $page = $this->pageFactory->create(); + $page->addHandle([ + 'default', + 'sales_order_view', + ]); + $page->getLayout()->generateXml(); + $orderItemsBlock = $page->getLayout()->getBlock('order_items')->unsetChild('order_totals'); + + return $orderItemsBlock->toHtml(); + } - /** @var \Magento\Sales\Block\Order\Items model */ - $this->model = $this->layout->createBlock(\Magento\Sales\Block\Order\Items::class, 'items_block'); - $this->assertEquals($order, $this->model->getOrder()); + /** + * Assert order items list. + * + * @param Collection $orderItems + * @param string $blockHtml + * @return void + */ + private function assertOrderItems(Collection $orderItems, string $blockHtml): void + { + $this->assertNotCount(0, $orderItems, 'Order items collection is empty'); + $fieldsToCheck = [ + 'name' => "/td[contains(@class, 'name')]/strong[contains(text(), '%s')]", + 'sku' => "/td[contains(@class, 'sku') and contains(text(), '%s')]", + 'price' => "/td[contains(@class, 'price')]//span[contains(text(), '%01.2f')]", + 'qty_ordered' => "/td[contains(@class, 'qty')]//span[contains(text(), '" . __('Ordered') + . "')]/following-sibling::span[contains(text(), '%d')]", + 'row_total' => "/td[contains(@class, 'subtotal')]//span[contains(text(), '%01.2f')]", + ]; + foreach ($orderItems as $item) { + $itemRowXpath = sprintf("//tr[@id='order-item-row-%s']", $item->getItemId()); + foreach ($fieldsToCheck as $key => $xpath) { + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath(sprintf($itemRowXpath . $xpath, $item->getData($key)), $blockHtml), + sprintf('Item %s wasn\'t found or not equals to %s.', $key, $item->getData($key)) + ); + } + } } /** - * Register order in registry + * Register order in registry. * - * @return \Magento\Sales\Model\Order + * @param OrderInterface $order + * @return void */ - private function registerOrder() + private function registerOrder(OrderInterface $order): void { - /** @var \Magento\Sales\Model\Order $order */ - $order = $this->objectManager->get(\Magento\Sales\Model\Order::class); - $order->loadByIncrementId('100000001'); + $this->registry->unregister('current_order'); $this->registry->register('current_order', $order); - return $order; } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/TotalsTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/TotalsTest.php index b23e7bcc140d4..7361ddc985b21 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Block/Order/TotalsTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Order/TotalsTest.php @@ -3,54 +3,129 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Block\Order; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\Element\Context; +use Magento\Framework\View\Element\Text; +use Magento\Framework\View\Layout; +use Magento\Framework\View\LayoutInterface; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\Xpath; +use PHPUnit\Framework\TestCase; + /** + * Tests for order totals block. + * * @magentoAppArea frontend + * @magentoDbIsolation enabled */ -class TotalsTest extends \PHPUnit\Framework\TestCase +class TotalsTest extends TestCase { - public function testToHtmlChildrenInitialized() + /** @var ObjectManagerInterface */ + private $objectManager; + + /** @var Layout */ + private $layout; + + /** @var Totals */ + private $block; + + /** @var OrderInterfaceFactory */ + private $orderFactory; + + /** + * @inheritdoc + */ + protected function setUp() { - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) - ->setAreaCode('frontend'); + parent::setUp(); - /** @var $layout \Magento\Framework\View\Layout */ - $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\View\LayoutInterface::class - ); - /** @var \Magento\Sales\Block\Order\Totals $block */ - $block = $layout->createBlock(\Magento\Sales\Block\Order\Totals::class, 'block'); - $block->setOrder( - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Sales\Model\Order::class) - )->setTemplate( - 'order/totals.phtml' - ); + $this->objectManager = Bootstrap::getObjectManager(); + $this->layout = $this->objectManager->get(LayoutInterface::class); + $this->block = $this->layout->createBlock(Totals::class, 'block'); + $this->orderFactory = $this->objectManager->get(OrderInterfaceFactory::class); + } - $context = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\View\Element\Context::class - ); - $childOne = $this->getMockBuilder(\Magento\Framework\View\Element\Text::class) + /** + * @magentoAppIsolation enabled + * + * @return void + */ + public function testToHtmlChildrenInitialized(): void + { + $this->block->setOrder($this->orderFactory->create())->setTemplate('order/totals.phtml'); + $context = $this->objectManager->get(Context::class); + $childOne = $this->getMockBuilder(Text::class) ->setMethods(['initTotals']) ->setConstructorArgs([$context]) ->getMock(); $childOne->expects($this->once())->method('initTotals'); - $layout->addBlock($childOne, 'child1', 'block'); - - $childTwo = $this->getMockBuilder(\Magento\Framework\View\Element\Text::class) + $this->layout->addBlock($childOne, 'child1', 'block'); + $childTwo = $this->getMockBuilder(Text::class) ->setMethods(['initTotals']) ->setConstructorArgs([$context]) ->getMock(); $childTwo->expects($this->once())->method('initTotals'); - $layout->addBlock($childTwo, 'child2', 'block'); - - $childThree = $this->getMockBuilder(\Magento\Framework\View\Element\Text::class) + $this->layout->addBlock($childTwo, 'child2', 'block'); + $childThree = $this->getMockBuilder(Text::class) ->setMethods(['initTotals']) ->setConstructorArgs([$context]) ->getMock(); $childThree->expects($this->once())->method('initTotals'); - $layout->addBlock($childThree, 'child3', 'block'); + $this->layout->addBlock($childThree, 'child3', 'block'); + $this->block->toHtml(); + } - $block->toHtml(); + /** + * @magentoDataFixture Magento/Sales/_files/customer_order_with_two_items.php + * + * @return void + */ + public function testOrderTotalsBlock(): void + { + $order = $this->orderFactory->create()->loadByIncrementId('100000555'); + $blockHtml = $this->block->setTemplate('Magento_Sales::order/totals.phtml')->setOrder($order)->toHtml(); + $message = '"%s" for order wasn\'t found or not equals to %01.2f'; + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//th[contains(text(), '%s')]/following-sibling::td/span[contains(text(), '%01.2f')]", + __('Subtotal'), + $order->getSubtotal() + ), + $blockHtml + ), + sprintf($message, __('Subtotal'), $order->getSubtotal()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//th[contains(text(), '%s')]/following-sibling::td/span[contains(text(), '%01.2f')]", + __('Shipping & Handling'), + $order->getShippingAmount() + ), + $blockHtml + ), + sprintf($message, __('Shipping & Handling'), $order->getShippingAmount()) + ); + $this->assertEquals( + 1, + Xpath::getElementsCountForXpath( + sprintf( + "//tr[contains(@class, 'grand_total') and contains(.//strong, '%s')]" + . "//span[contains(text(), '%01.2f')]", + __('Grand Total'), + $order->getGrandTotal() + ), + $blockHtml + ), + sprintf($message, __('Grand Total'), $order->getGrandTotal()) + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/customer_order_with_two_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/customer_order_with_two_items.php new file mode 100644 index 0000000000000..5270b291a56d4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/customer_order_with_two_items.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product\Type; +use Magento\Sales\Api\Data\OrderAddressInterfaceFactory; +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\Sales\Api\Data\OrderPaymentInterfaceFactory; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Api\Data\OrderItemInterfaceFactory; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Address; + +require __DIR__ . '/../../../Magento/Customer/_files/customer_with_uk_address.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_duplicated.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/products_new.php'; + +/** @var OrderInterfaceFactory $orderFactory */ +$orderFactory = $objectManager->get(OrderInterfaceFactory::class); +/** @var OrderItemInterfaceFactory $orderItemFactory */ +$orderItemFactory = $objectManager->get(OrderItemInterfaceFactory::class); +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->get(OrderRepositoryInterface::class); +/** @var OrderAddressInterfaceFactory $orderAddressFactory */ +$orderAddressFactory = $objectManager->get(OrderAddressInterfaceFactory::class); +/** @var OrderPaymentInterfaceFactory $orderPaymentFactory */ +$orderPaymentFactory = $objectManager->get(OrderPaymentInterfaceFactory::class); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$productRepository->cleanCache(); + +$billingAddress = $orderAddressFactory->create(['data' => $customerAddress->getData()]); +$billingAddress->setAddressType(Address::TYPE_BILLING); + +$shippingAddress = $orderAddressFactory->create(['data' => $customerAddress->getData()]); +$shippingAddress->setAddressType(Address::TYPE_SHIPPING) + ->setStreet('street for shipping') + ->setRegion('North West') + ->setPostcode('GU16 7HF') + ->setShippingMethod('flatrate_flatrate'); + +$orderPayment = $orderPaymentFactory->create(); +$orderPayment->setMethod('checkmo') + ->setAdditionalInformation('last_trans_id', '11122') + ->setAdditionalInformation( + 'metadata', + ['type' => 'free', 'fraudulent' => false] + ); + +$firstProduct = $productRepository->get('simple-1'); +$firstOrderItem = $orderItemFactory->create(); +$firstOrderItem->setProductId($firstProduct->getId()) + ->setQtyOrdered(1) + ->setBasePrice($firstProduct->getPrice()) + ->setPrice($firstProduct->getPrice()) + ->setRowTotal($firstProduct->getPrice()) + ->setProductType(Type::TYPE_SIMPLE) + ->setName($firstProduct->getName()) + ->setSku($firstProduct->getSku()); + +$secondProduct = $productRepository->get('simple'); +$secondOrderItem = $orderItemFactory->create(); +$secondOrderItem->setProductId($secondProduct->getId()) + ->setQtyOrdered(1) + ->setBasePrice($secondProduct->getPrice()) + ->setPrice($secondProduct->getPrice()) + ->setRowTotal($secondProduct->getPrice()) + ->setProductType(Type::TYPE_SIMPLE) + ->setName($secondProduct->getName()) + ->setSku($secondProduct->getSku()); + +$order = $orderFactory->create(); +$order->setIncrementId('100000555') + ->setState(Order::STATE_PROCESSING) + ->setStatus(Order::STATE_PROCESSING) + ->setSubtotal(20) + ->setShippingAmount(10) + ->setGrandTotal(30) + ->setBaseSubtotal(20) + ->setBaseShippingAmount(10) + ->setBaseGrandTotal(30) + ->setCustomerIsGuest(false) + ->setCustomerEmail($customerDataModel->getEmail()) + ->setCustomerId($customerDataModel->getId()) + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress) + ->setShippingDescription('Flat Rate - Fixed') + ->setStoreId($mainWebsite->getDefaultStore()->getId()) + ->addItem($firstOrderItem) + ->addItem($secondOrderItem) + ->setPayment($orderPayment); +$orderRepository->save($order); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/customer_order_with_two_items_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/customer_order_with_two_items_rollback.php new file mode 100644 index 0000000000000..a6225b247466e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/customer_order_with_two_items_rollback.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Sales\Api\Data\OrderInterfaceFactory; +use Magento\Sales\Api\OrderRepositoryInterface; + +require __DIR__ . '/../../../Magento/Customer/_files/customer_with_uk_address_rollback.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_duplicated_rollback.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/products_new_rollback.php'; + +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->get(OrderRepositoryInterface::class); +/** @var OrderInterfaceFactory $orderFactory */ +$orderFactory = $objectManager->create(OrderInterfaceFactory::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +$order = $orderFactory->create()->loadByIncrementId('100000555'); +if ($order->getId()) { + $orderRepository->delete($order); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoices_for_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoices_for_items.php new file mode 100644 index 0000000000000..dbec254b69482 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoices_for_items.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Sales\Api\Data\InvoiceItemCreationInterfaceFactory; +use Magento\Sales\Api\InvoiceOrderInterface; + +require __DIR__ . '/../../../Magento/Sales/_files/customer_order_with_two_items.php'; + +/** @var InvoiceItemCreationInterfaceFactory $invoiceItemFactory */ +$invoiceItemFactory = $objectManager->get(InvoiceItemCreationInterfaceFactory::class); +/** @var InvoiceOrderInterface $invoiceOrder */ +$invoiceOrder = $objectManager->get(InvoiceOrderInterface::class); + +foreach ($order->getItems() as $orderItem) { + $invoiceItem = $invoiceItemFactory->create(); + $invoiceItem->setOrderItemId($orderItem->getItemId()); + $invoiceItem->setQty($orderItem->getQtyOrdered()); + $invoiceOrder->execute($order->getId(), false, [$invoiceItem]); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoices_for_items_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoices_for_items_rollback.php new file mode 100644 index 0000000000000..91200f3c1b46c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoices_for_items_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require __DIR__ . '/../../../Magento/Sales/_files/customer_order_with_two_items_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/refunds_for_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/refunds_for_items.php new file mode 100644 index 0000000000000..d8b94866adbb8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/refunds_for_items.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Sales\Api\Data\CreditmemoItemCreationInterfaceFactory; +use Magento\Sales\Api\RefundOrderInterface; + +require __DIR__ . '/../../../Magento/Sales/_files/invoices_for_items.php'; + +/** @var CreditmemoItemCreationInterfaceFactory $creditmemoItemFactory */ +$creditmemoItemFactory = $objectManager->get(CreditmemoItemCreationInterfaceFactory::class); +/** @var RefundOrderInterface $refundOrder */ +$refundOrder = $objectManager->get(RefundOrderInterface::class); + +foreach ($order->getItems() as $item) { + $creditmemoItem = $creditmemoItemFactory->create(); + $creditmemoItem->setOrderItemId($item->getId()); + $creditmemoItem->setQty($item->getQtyOrdered()); + $refundOrder->execute($order->getId(), [$creditmemoItem]); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/refunds_for_items_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/refunds_for_items_rollback.php new file mode 100644 index 0000000000000..67a4321c182ec --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/refunds_for_items_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require __DIR__ . '/../../../Magento/Sales/_files/invoices_for_items_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php index 4f5c332269cf0..05c12eee3418a 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php @@ -6,6 +6,8 @@ namespace Magento\Framework\Test\Unit\View\Element; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer; +use PHPUnit\Framework\MockObject\MockObject; class UiComponentFactoryTest extends \PHPUnit\Framework\TestCase { @@ -15,25 +17,25 @@ class UiComponentFactoryTest extends \PHPUnit\Framework\TestCase /** @var ObjectManagerHelper */ protected $objectManagerHelper; - /** @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\ObjectManagerInterface|MockObject */ protected $objectManagerMock; - /** @var \Magento\Framework\Data\Argument\InterpreterInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Data\Argument\InterpreterInterface|MockObject */ protected $interpreterMock; - /** @var \Magento\Framework\View\Element\UiComponent\ContextFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\UiComponent\ContextFactory|MockObject */ protected $contextFactoryMock; - /** @var \Magento\Framework\Config\DataInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Config\DataInterfaceFactory|MockObject */ protected $dataInterfaceFactoryMock; - /** @var \SafeReflectionClass|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \SafeReflectionClass|MockObject */ protected $safeReflectionClassMock; - /** @var \SafeReflectionClass|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \SafeReflectionClass|MockObject */ protected $safeReflectionClassMock2; - /** @var \Magento\Ui\Config\Reader\Definition\Data|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Ui\Config\Reader\Definition\Data|MockObject */ protected $dataMock; protected function setUp() @@ -58,6 +60,9 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); $this->dataMock = $this->createMock(\Magento\Framework\Config\DataInterface::class); + $sanitizerMock = $this->createMock(Sanitizer::class); + $sanitizerMock->method('sanitize')->willReturnArgument(0); + $sanitizerMock->method('sanitizeComponentMetadata')->willReturnArgument(0); $this->objectManagerHelper = new ObjectManagerHelper($this); $this->model = $this->objectManagerHelper->getObject( \Magento\Framework\View\Element\UiComponentFactory::class, @@ -68,7 +73,8 @@ protected function setUp() 'configFactory' => $this->dataInterfaceFactoryMock, 'data' => [], 'componentChildFactories' => [], - 'definitionData' => $this->dataMock + 'definitionData' => $this->dataMock, + 'sanitizer' => $sanitizerMock ] ); } diff --git a/dev/tests/integration/testsuite/Magento/Setup/Module/DataSetupTest.php b/dev/tests/integration/testsuite/Magento/Setup/Module/DataSetupTest.php index 425840b44ba0e..4c35d9882a0ac 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Module/DataSetupTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Module/DataSetupTest.php @@ -39,7 +39,7 @@ public function testUpdateTableRow() } /** - * @expectedException \Zend_Db_Statement_Exception + * @expectedException \Magento\Framework\DB\Adapter\TableNotFoundException */ public function testDeleteTableRow() { @@ -47,8 +47,7 @@ public function testDeleteTableRow() } /** - * @covers \Magento\Setup\Module\DataSetup::updateTableRow - * @expectedException \Zend_Db_Statement_Exception + * @expectedException \Magento\Framework\DB\Adapter\TableNotFoundException */ public function testUpdateTableRowNameConversion() { diff --git a/dev/tests/integration/testsuite/Magento/Translation/Model/Js/DataProviderTest.php b/dev/tests/integration/testsuite/Magento/Translation/Model/Js/DataProviderTest.php new file mode 100644 index 0000000000000..305beae5b9562 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Translation/Model/Js/DataProviderTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Translation\Model\Js; + +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\TranslateInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Translation\Model\ResourceModel\StringUtils; +use PHPUnit\Framework\TestCase; + +/** + * Integration tests for \Magento\Translation\Model\Js\DataProvider class. + */ +class DataProviderTest extends TestCase +{ + /** + * @var StringUtils + */ + private $stringUtils; + + /** + * @var TranslateInterface + */ + private $translate; + + /** + * @var DataProviderInterface + */ + private $translationDataProvider; + + /** + * @inheritdoc + */ + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->stringUtils = $objectManager->get(StringUtils::class); + $this->translate = $objectManager->get(TranslateInterface::class); + $this->translationDataProvider = $objectManager->get(DataProviderInterface::class); + } + + /** + * Test translation data. + * + * @magentoAppArea frontend + * @magentoConfigFixture default_store dev/translate_inline/active 1 + */ + public function testGetData() + { + $expectedDictionary = ['Proceed to Checkout' => 'Proceed to Checkout - Translated']; + + $this->stringUtils->saveTranslate('Proceed to Checkout', 'Proceed to Checkout - Translated'); + $this->translate->setLocale('en_US')->loadData('frontend', true); + $dictionary = $this->translationDataProvider->getData('Magento/luma'); + $this->assertEquals($expectedDictionary, $dictionary); + } + + /** + * @inheritdoc + */ + public function tearDown() + { + try { + $this->stringUtils->deleteTranslate('Proceed to Checkout'); + } catch (NoSuchEntityException $exception) { + // translate already deleted + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Ui/Component/Form/Element/MultiSelectTest.php b/dev/tests/integration/testsuite/Magento/Ui/Component/Form/Element/MultiSelectTest.php new file mode 100644 index 0000000000000..6c7e369419a55 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ui/Component/Form/Element/MultiSelectTest.php @@ -0,0 +1,89 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Ui\Component\Form\Element; + +use Magento\Framework\Data\OptionSourceInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test MultiSelect component. + */ +class MultiSelectTest extends TestCase +{ + /** + * @var MultiSelectFactory + */ + private $factory; + + /** + * @inheritDoc + */ + protected function setUp() + { + $this->factory = Bootstrap::getObjectManager()->get(MultiSelectFactory::class); + } + + /** + * Options data to verify + * + * @return array + */ + public function getTestOptions(): array + { + return [ + 'List' => [ + [ + ['value' => '${\'my-value\'}', 'label' => 'My label'], + ['value' => '1', 'label' => 'Label'], + ['value' => '${\'my-value-2\'}', 'label' => 'This is ${\'My label\'}'] + ], + [ + ['value' => '${\'my-value\'}', 'label' => 'My label', '__disableTmpl' => ['value' => true]], + ['value' => '1', 'label' => 'Label'], + [ + 'value' => '${\'my-value-2\'}', + 'label' => 'This is ${\'My label\'}', + '__disableTmpl' => ['value' => true, 'label' => true] + ] + ] + ], + 'provider' => [ + new class implements OptionSourceInterface + { + /** + * @inheritDoc + */ + public function toOptionArray() + { + return [['value' => '${\'value\'}', 'label' => 'Test']]; + } + }, + [['value' => '${\'value\'}', 'label' => 'Test', '__disableTmpl' => ['value' => true]]] + ] + ]; + } + + /** + * Check that options received from an options provider properly initiated. + * + * @param array|OptionSourceInterface $options Options provided + * @param array $expected Expected initialized options + * @return void + * @dataProvider getTestOptions + */ + public function testOptions($options, array $expected): void + { + /** @var MultiSelect $component */ + $component = $this->factory->create(['options' => $options]); + $component->prepare(); + + $this->assertEquals($expected, $component->getData('config')['options']); + } +} diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js index ac6e230e7ed1c..f46ff6b30abbe 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/form/ui-select.test.js @@ -624,6 +624,24 @@ define([ expect(obj.options).toHaveBeenCalledWith([]); expect(obj.processRequest).toHaveBeenCalledWith(searchKey, 1); }); + it('Should update cacheOptions if response was cached', function () { + var searchKey = 'cake', + searchResult = 'piece a cake'; + + obj.deviation = 30; + obj.cachedSearchResults = { + cake: { + options: [searchResult], + lastPage: 1, + total: 1 + } + }; + + spyOn(obj, 'options'); + obj.loadOptions(searchKey); + expect(obj.options).toHaveBeenCalledWith([searchResult]); + expect(obj.cacheOptions.plain).toContain(searchResult); + }); }); describe('"isSearchKeyCached" method', function () { it('Should return false if searchKey has already been cached and total covers > 1 page', function () { @@ -672,7 +690,7 @@ define([ }); }); describe('"processRequest" method', function () { - it('Should store options successfully fetched from ajax request', function () { + it('Should store options and update cache successfully after fetched from ajax request', function () { var ajaxRequest, successfulAjaxResponse = { options: { @@ -686,6 +704,24 @@ define([ } }; + // place a number of options to cache prior fetch + obj.cacheOptions.plain = [{ + '2053': { + value: '2057', + label: 'testProductName5a8ddfd933b5c', + 'is_active': 1, + path: 'testSku5a8ddfd933b5c', + optgroup: false + }, + '2054': { + value: '2058', + label: 'testProductName5a8ddfd933b5c', + 'is_active': 1, + path: 'testSku5a8ddfd933b5c', + optgroup: false + } + }]; + $.ajax = jasmine.createSpy().and.callFake(function (request) { ajaxRequest = request.success.bind(obj); }); @@ -693,7 +729,18 @@ define([ expect(obj.processRequest()).toBeUndefined(); ajaxRequest(successfulAjaxResponse); - expect(JSON.stringify(obj.options())).toEqual(JSON.stringify([successfulAjaxResponse.options['2053']])); + + expect( + JSON.stringify(obj.options()) + ).toEqual( + JSON.stringify([successfulAjaxResponse.options['2053']]) + ); + + expect( + JSON.stringify(obj.cacheOptions.plain) + ).toEqual( + JSON.stringify([successfulAjaxResponse.options['2053']]) + ); }); }); }); diff --git a/dev/tests/static/framework/Magento/TestFramework/Dependency/AnalyticsConfigRule.php b/dev/tests/static/framework/Magento/TestFramework/Dependency/AnalyticsConfigRule.php index b1a6da5e43822..d6f9ba6268cf9 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Dependency/AnalyticsConfigRule.php +++ b/dev/tests/static/framework/Magento/TestFramework/Dependency/AnalyticsConfigRule.php @@ -30,7 +30,7 @@ public function getDependencyInfo($currentModule, $fileType, $file, &$contents) $module = implode('\\', array_slice($classParts, 0, 2)); if (strtolower($currentModule) !== strtolower($module)) { $dependenciesInfo[] = [ - 'module' => $module, + 'modules' => [$module], 'type' => RuleInterface::TYPE_HARD, 'source' => $file, ]; diff --git a/dev/tests/static/framework/Magento/TestFramework/Dependency/DbRule.php b/dev/tests/static/framework/Magento/TestFramework/Dependency/DbRule.php index 3e3fa7686a296..cb3a9e2cc9c35 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Dependency/DbRule.php +++ b/dev/tests/static/framework/Magento/TestFramework/Dependency/DbRule.php @@ -52,7 +52,7 @@ public function getDependencyInfo($currentModule, $fileType, $file, &$contents) } if (strtolower($currentModule) !== strtolower($this->_moduleTableMap[$table])) { $dependenciesInfo[] = [ - 'module' => $this->_moduleTableMap[$table], + 'modules' => [$this->_moduleTableMap[$table]], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => $table, ]; @@ -61,7 +61,7 @@ public function getDependencyInfo($currentModule, $fileType, $file, &$contents) } foreach ($unKnowTables as $tables) { foreach ($tables as $table) { - $dependenciesInfo[] = ['module' => 'Unknown', 'source' => $table]; + $dependenciesInfo[] = ['modules' => ['Unknown'], 'source' => $table]; } } return $dependenciesInfo; diff --git a/dev/tests/static/framework/Magento/TestFramework/Dependency/DiRule.php b/dev/tests/static/framework/Magento/TestFramework/Dependency/DiRule.php index b3ee0a2880308..122c3da3afcb1 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Dependency/DiRule.php +++ b/dev/tests/static/framework/Magento/TestFramework/Dependency/DiRule.php @@ -93,7 +93,7 @@ public function getDependencyInfo($currentModule, $fileType, $file, &$contents) continue; } $dependenciesInfo[] = [ - 'module' => $referenceModule, + 'modules' => [$referenceModule], 'type' => $type, 'source' => $matches['class'], ]; diff --git a/dev/tests/static/framework/Magento/TestFramework/Dependency/LayoutRule.php b/dev/tests/static/framework/Magento/TestFramework/Dependency/LayoutRule.php index 27017c6069538..75825077e03ec 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Dependency/LayoutRule.php +++ b/dev/tests/static/framework/Magento/TestFramework/Dependency/LayoutRule.php @@ -133,8 +133,8 @@ public function getDependencyInfo($currentModule, $fileType, $file, &$contents) * * Ex.: <element module="{module}"> * - * @param $currentModule - * @param $contents + * @param string $currentModule + * @param string $contents * @return array */ protected function _caseAttributeModule($currentModule, &$contents) @@ -154,8 +154,8 @@ protected function _caseAttributeModule($currentModule, &$contents) * Ex.: <block class="{name}"> * <block template="{path}"> * - * @param $currentModule - * @param $contents + * @param string $currentModule + * @param string $contents * @return array */ protected function _caseElementBlock($currentModule, &$contents) @@ -182,8 +182,8 @@ protected function _caseElementBlock($currentModule, &$contents) * <file>{path} * <element helper="{name}"> * - * @param $currentModule - * @param $contents + * @param string $currentModule + * @param string $contents * @return array */ protected function _caseElementAction($currentModule, &$contents) @@ -218,9 +218,9 @@ protected function _caseElementAction($currentModule, &$contents) * * Ex.: <layout><{name}>...</layout> * - * @param $currentModule - * @param $file - * @param $contents + * @param string $currentModule + * @param string $file + * @param string $contents * @return array */ protected function _caseLayoutHandle($currentModule, $file, &$contents) @@ -235,11 +235,8 @@ protected function _caseLayoutHandle($currentModule, $file, &$contents) $result = []; foreach ((array)$xml->xpath('/layout/child::*') as $element) { $check = $this->_checkDependencyLayoutHandle($currentModule, $area, $element->getName()); - $modules = isset($check['module']) ? $check['module'] : null; + $modules = isset($check['modules']) ? $check['modules'] : null; if ($modules) { - if (!is_array($modules)) { - $modules = [$modules]; - } foreach ($modules as $module) { $result[$module] = [ 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, @@ -256,9 +253,9 @@ protected function _caseLayoutHandle($currentModule, $file, &$contents) * * Ex.: <layout_name parent="{name}"> * - * @param $currentModule - * @param $file - * @param $contents + * @param string $currentModule + * @param string $file + * @param string $contents * @return array */ protected function _caseLayoutHandleParent($currentModule, $file, &$contents) @@ -273,11 +270,8 @@ protected function _caseLayoutHandleParent($currentModule, $file, &$contents) $result = []; foreach ((array)$xml->xpath('/layout/child::*/@parent') as $element) { $check = $this->_checkDependencyLayoutHandle($currentModule, $area, (string)$element); - $modules = isset($check['module']) ? $check['module'] : null; + $modules = isset($check['modules']) ? $check['modules'] : null; if ($modules) { - if (!is_array($modules)) { - $modules = [$modules]; - } foreach ($modules as $module) { $result[$module] = [ 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_HARD, @@ -294,9 +288,9 @@ protected function _caseLayoutHandleParent($currentModule, $file, &$contents) * * Ex.: <update handle="{name}" /> * - * @param $currentModule - * @param $file - * @param $contents + * @param string $currentModule + * @param string $file + * @param string $contents * @return array */ protected function _caseLayoutHandleUpdate($currentModule, $file, &$contents) @@ -311,11 +305,8 @@ protected function _caseLayoutHandleUpdate($currentModule, $file, &$contents) $result = []; foreach ((array)$xml->xpath('//update/@handle') as $element) { $check = $this->_checkDependencyLayoutHandle($currentModule, $area, (string)$element); - $modules = isset($check['module']) ? $check['module'] : null; + $modules = isset($check['modules']) ? $check['modules'] : null; if ($modules) { - if (!is_array($modules)) { - $modules = [$modules]; - } foreach ($modules as $module) { $result[$module] = [ 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, @@ -332,9 +323,9 @@ protected function _caseLayoutHandleUpdate($currentModule, $file, &$contents) * * Ex.: <reference name="{name}"> * - * @param $currentModule - * @param $file - * @param $contents + * @param string $currentModule + * @param string $file + * @param string $contents * @return array */ protected function _caseLayoutReference($currentModule, $file, &$contents) @@ -349,12 +340,14 @@ protected function _caseLayoutReference($currentModule, $file, &$contents) $result = []; foreach ((array)$xml->xpath('//reference/@name') as $element) { $check = $this->_checkDependencyLayoutBlock($currentModule, $area, (string)$element); - $module = isset($check['module']) ? $check['module'] : null; - if ($module) { - $result[$module] = [ - 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_SOFT, - 'source' => (string)$element, - ]; + $modules = isset($check['modules']) ? $check['modules'] : null; + if ($modules) { + foreach ($modules as $module) { + $result[$module] = [ + 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, + 'source' => (string)$element, + ]; + } } } return $this->_getUniqueDependencies($result); @@ -363,8 +356,8 @@ protected function _caseLayoutReference($currentModule, $file, &$contents) /** * Search dependencies by defined regexp patterns * - * @param $currentModule - * @param $contents + * @param string $currentModule + * @param string $contents * @param array $patterns * @return array */ @@ -390,14 +383,14 @@ protected function _checkDependenciesByRegexp($currentModule, &$contents, $patte * Check layout handle dependency * * Return: array( - * 'module' // dependent module + * 'modules' // dependent modules * 'source' // source text * ) * - * @param $currentModule - * @param $area - * @param $handle - * @return array + * @param admin $currentModule + * @param string $area + * @param string $handle + * @return string[] */ protected function _checkDependencyLayoutHandle($currentModule, $area, $handle) { @@ -411,7 +404,7 @@ protected function _checkDependencyLayoutHandle($currentModule, $area, $handle) // CASE 1: Single dependency $modules = $this->_mapRouters[$router]; if (!in_array($currentModule, $modules)) { - return ['module' => $modules]; + return ['modules' => $modules]; } } @@ -419,18 +412,18 @@ protected function _checkDependencyLayoutHandle($currentModule, $area, $handle) // CASE 2: No dependencies $modules = $this->_mapLayoutHandles[$area][$handle]; if (isset($modules[$currentModule])) { - return ['module' => null]; + return ['modules' => []]; } // CASE 3: Single dependency if (1 == count($modules)) { - return ['module' => current($modules)]; + return ['modules' => $modules]; } // CASE 4: Default module dependency $defaultModule = $this->_getDefaultModuleName($area); if (isset($modules[$defaultModule])) { - return ['module' => $defaultModule]; + return ['modules' => [$defaultModule]]; } } @@ -441,14 +434,14 @@ protected function _checkDependencyLayoutHandle($currentModule, $area, $handle) * Check layout block dependency * * Return: array( - * 'module' // dependent module + * 'modules' // dependent modules * 'source' // source text * ) * - * @param $currentModule - * @param $area - * @param $block - * @return array + * @param string $currentModule + * @param string $area + * @param string $block + * @return string[] */ protected function _checkDependencyLayoutBlock($currentModule, $area, $block) { @@ -456,18 +449,18 @@ protected function _checkDependencyLayoutBlock($currentModule, $area, $block) // CASE 1: No dependencies $modules = $this->_mapLayoutBlocks[$area][$block]; if (isset($modules[$currentModule])) { - return ['module' => null]; + return ['modules' => []]; } // CASE 2: Single dependency if (1 == count($modules)) { - return ['module' => current($modules)]; + return ['modules' => $modules]; } // CASE 3: Default module dependency $defaultModule = $this->_getDefaultModuleName($area); if (isset($modules[$defaultModule])) { - return ['module' => $defaultModule]; + return ['modules' => [$defaultModule]]; } } return []; @@ -476,7 +469,7 @@ protected function _checkDependencyLayoutBlock($currentModule, $area, $block) /** * Get area from file path * - * @param $file + * @param string $file * @return string */ protected function _getAreaByFile($file) @@ -498,7 +491,7 @@ protected function _getUniqueDependencies($dependencies = []) { $result = []; foreach ($dependencies as $module => $value) { - $result[] = ['module' => $module, 'type' => $value['type'], 'source' => $value['source']]; + $result[] = ['modules' => [$module], 'type' => $value['type'], 'source' => $value['source']]; } return $result; } @@ -507,7 +500,7 @@ protected function _getUniqueDependencies($dependencies = []) * Retrieve default module name (by area) * * @param string $area - * @return null + * @return string|null */ protected function _getDefaultModuleName($area = 'default') { diff --git a/dev/tests/static/framework/Magento/TestFramework/Dependency/PhpRule.php b/dev/tests/static/framework/Magento/TestFramework/Dependency/PhpRule.php index 913cc9448b978..7ae854885affa 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Dependency/PhpRule.php +++ b/dev/tests/static/framework/Magento/TestFramework/Dependency/PhpRule.php @@ -94,7 +94,6 @@ public function __construct( ) { $this->_mapRouters = $mapRouters; $this->_mapLayoutBlocks = $mapLayoutBlocks; - $this->_namespaces = implode('|', \Magento\Framework\App\Utility\Files::init()->getNamespaces()); $this->pluginMap = $pluginMap ?: null; $this->routeMapper = new RouteMapper(); $this->whitelists = $whitelists; @@ -184,7 +183,7 @@ private function caseClassesAndIdentifiers($currentModule, $file, &$contents) } $dependenciesInfo[] = [ - 'module' => $referenceModule, + 'modules' => [$referenceModule], 'type' => $dependencyType, 'source' => $dependencyClass, ]; @@ -317,11 +316,8 @@ protected function _caseGetUrl(string $currentModule, string &$contents): array $actionName ); if (!in_array($currentModule, $modules)) { - if (count($modules) === 1) { - $modules = reset($modules); - } $dependencies[] = [ - 'module' => $modules, + 'modules' => $modules, 'type' => RuleInterface::TYPE_HARD, 'source' => $item['source'], ]; @@ -361,12 +357,14 @@ protected function _caseLayoutBlock(string $currentModule, string $fileType, str continue; } $check = $this->_checkDependencyLayoutBlock($currentModule, $area, $match['block']); - $module = isset($check['module']) ? $check['module'] : null; - if ($module) { - $result[$module] = [ - 'type' => RuleInterface::TYPE_HARD, - 'source' => $match['source'], - ]; + $modules = isset($check['modules']) ? $check['modules'] : null; + if ($modules) { + foreach ($modules as $module) { + $result[$module] = [ + 'type' => RuleInterface::TYPE_HARD, + 'source' => $match['source'], + ]; + } } } return $this->_getUniqueDependencies($result); @@ -395,7 +393,7 @@ protected function _getAreaByFile(string $file, string $fileType): ?string * Check layout block dependency * * Return: array( - * 'module' // dependent module + * 'modules' // dependent modules * 'source' // source text * ) * @@ -419,16 +417,16 @@ protected function _checkDependencyLayoutBlock(string $currentModule, ?string $a $modules = $this->_mapLayoutBlocks[$area][$block]; } if (isset($modules[$currentModule])) { - return ['module' => null]; + return ['modules' => []]; } // CASE 2: Single dependency if (1 == count($modules)) { - return ['module' => current($modules)]; + return ['modules' => $modules]; } // CASE 3: Default module dependency $defaultModule = $this->_getDefaultModuleName($area); if (isset($modules[$defaultModule])) { - return ['module' => $defaultModule]; + return ['modules' => [$defaultModule]]; } } // CASE 4: \Exception - Undefined block @@ -459,7 +457,7 @@ protected function _getUniqueDependencies($dependencies = []) { $result = []; foreach ($dependencies as $module => $value) { - $result[] = ['module' => $module, 'type' => $value['type'], 'source' => $value['source']]; + $result[] = ['modules' => [$module], 'type' => $value['type'], 'source' => $value['source']]; } return $result; } diff --git a/dev/tests/static/framework/Magento/TestFramework/Dependency/ReportsConfigRule.php b/dev/tests/static/framework/Magento/TestFramework/Dependency/ReportsConfigRule.php index ab450fba5781d..4c8daaebdd698 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Dependency/ReportsConfigRule.php +++ b/dev/tests/static/framework/Magento/TestFramework/Dependency/ReportsConfigRule.php @@ -43,7 +43,7 @@ public function getDependencyInfo($currentModule, $fileType, $file, &$contents) } if (strtolower($currentModule) !== strtolower($this->moduleTableMap[$table])) { $dependenciesInfo[] = [ - 'module' => $this->moduleTableMap[$table], + 'modules' => [$this->moduleTableMap[$table]], 'type' => RuleInterface::TYPE_HARD, 'source' => $table, ]; diff --git a/dev/tests/static/framework/Magento/TestFramework/Dependency/Route/RouteMapper.php b/dev/tests/static/framework/Magento/TestFramework/Dependency/Route/RouteMapper.php index 315bb2ae26b02..6cc55b49edcca 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Dependency/Route/RouteMapper.php +++ b/dev/tests/static/framework/Magento/TestFramework/Dependency/Route/RouteMapper.php @@ -154,7 +154,7 @@ function (&$modules) { * @param string $routeId * @param string $controllerName * @param string $actionName - * @return array + * @return string[] * @throws NoSuchActionException * @throws \Exception */ diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DbRuleTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DbRuleTest.php index 986ddf72ec3d3..9a617ba9b8da2 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DbRuleTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DbRuleTest.php @@ -37,7 +37,7 @@ public function getDependencyInfoDataProvider() 'any', '/app/some/path/Setup/some-file.php', '$install->getTableName("unknown_table")', - [['module' => 'Unknown', 'source' => 'unknown_table']] + [['modules' => ['Unknown'], 'source' => 'unknown_table']] ], [ 'SomeModule', @@ -51,7 +51,7 @@ public function getDependencyInfoDataProvider() '$install->getTableName("some_table")', [ [ - 'module' => 'SomeModule', + 'modules' => ['SomeModule'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'some_table', ] diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DiRuleTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DiRuleTest.php index 1f4c11f17e9e5..aa69b72ef6419 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DiRuleTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/DiRuleTest.php @@ -48,32 +48,32 @@ public function getDependencyInfoDataProvider() $this->getFileContent('di_external_dependency.xml'), [ [ - 'module' => 'Magento\ExternalModule3', + 'modules' => ['Magento\ExternalModule3'], 'type' => RuleInterface::TYPE_SOFT, 'source' => 'Magento\ExternalModule3\Some\Another\Class' ], [ - 'module' => 'Magento\ExternalModule5', + 'modules' => ['Magento\ExternalModule5'], 'type' => RuleInterface::TYPE_SOFT, 'source' => 'Magento\ExternalModule5\Some\Another\Class' ], [ - 'module' => 'Magento\ExternalModule6', + 'modules' => ['Magento\ExternalModule6'], 'type' => RuleInterface::TYPE_SOFT, 'source' => 'Magento\ExternalModule6\Some\Plugin\Class' ], [ - 'module' => 'Magento\ExternalModule1', + 'modules' => ['Magento\ExternalModule1'], 'type' => RuleInterface::TYPE_HARD, 'source' => 'Magento\ExternalModule1\Some\Argument1' ], [ - 'module' => 'Magento\ExternalModule2', + 'modules' => ['Magento\ExternalModule2'], 'type' => RuleInterface::TYPE_HARD, 'source' => 'Magento\ExternalModule2\Some\Argument2' ], [ - 'module' => 'Magento\ExternalModule4', + 'modules' => ['Magento\ExternalModule4'], 'type' => RuleInterface::TYPE_HARD, 'source' => 'Magento\ExternalModule4\Some\Argument3' ] @@ -84,12 +84,12 @@ public function getDependencyInfoDataProvider() $this->getFileContent('di_virtual_dependency.xml'), [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => RuleInterface::TYPE_HARD, 'source' => 'Magento\AnotherModule\Some\Class1', ], [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => RuleInterface::TYPE_HARD, 'source' => 'Magento\AnotherModule\Some\Class2', ] diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/LayoutRuleTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/LayoutRuleTest.php index dd0e90eefe4f5..1ee2e8ca24791 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/LayoutRuleTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/LayoutRuleTest.php @@ -32,7 +32,7 @@ public function getDependencyInfoDataProvider() '<element module="Magento\AnotherModule"/>', [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, 'source' => '<element module="Magento\AnotherModule"/>', ] @@ -43,7 +43,7 @@ public function getDependencyInfoDataProvider() '<block class="Magento\AnotherModule\Several\Chunks"/>', [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_HARD, 'source' => '<block class="Magento\AnotherModule\Several\Chunks"/>', ] @@ -56,7 +56,7 @@ public function getDependencyInfoDataProvider() </any>', [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, 'source' => '<block template="Magento_AnotherModule::template/path.phtml"/>', ] @@ -67,7 +67,7 @@ public function getDependencyInfoDataProvider() '<block>Magento\AnotherModule\Several\Chunks</block>', [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, 'source' => '<block>Magento\AnotherModule\Several\Chunks</block>', ] @@ -78,7 +78,7 @@ public function getDependencyInfoDataProvider() '<template>Magento_AnotherModule::template/path.phtml</template>', [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, 'source' => '<template>Magento_AnotherModule::template/path.phtml</template>', ] @@ -89,7 +89,7 @@ public function getDependencyInfoDataProvider() '<file>Magento_AnotherModule::file/path.txt</file>', [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, 'source' => '<file>Magento_AnotherModule::file/path.txt</file>', ] @@ -100,7 +100,7 @@ public function getDependencyInfoDataProvider() '<any helper="Magento\AnotherModule\Several\Chunks::text"/>', [ [ - 'module' => 'Magento\AnotherModule', + 'modules' => ['Magento\AnotherModule'], 'type' => \Magento\Test\Integrity\DependencyTest::TYPE_SOFT, 'source' => '<any helper="Magento\AnotherModule\Several\Chunks::text"/>', ] @@ -120,7 +120,7 @@ public function testUpdatesRouterGetDependencyInfo($contents, $type) $model = new LayoutRule(['router_name' => ['Magento\RouterModule']], [], []); $this->assertEquals([], $model->getDependencyInfo('Magento\RouterModule', 'layout', 'any', $contents)); $this->assertEquals( - [['module' => 'Magento\RouterModule', 'type' => $type, 'source' => 'router_name_action']], + [['modules' => ['Magento\RouterModule'], 'type' => $type, 'source' => 'router_name_action']], $model->getDependencyInfo('Magento\AnotherModule', 'layout', 'any', $contents) ); } @@ -148,11 +148,11 @@ public function testLayoutGetDependencyInfo($contents, $type, $isHandle) $model->getDependencyInfo('Magento\DefaultHandleModule', 'layout', 'any', $contents) ); $this->assertEquals( - [['module' => 'Magento\DefaultHandleModule', 'type' => $type, 'source' => 'singlechunk']], + [['modules' => ['Magento\DefaultHandleModule'], 'type' => $type, 'source' => 'singlechunk']], $model->getDependencyInfo('any', 'layout', 'any', $contents) ); $this->assertEquals( - [['module' => 'Magento\AnyHandleModule', 'type' => $type, 'source' => 'any_handle_name']], + [['modules' => ['Magento\AnyHandleModule'], 'type' => $type, 'source' => 'any_handle_name']], $model->getDependencyInfo('any', 'layout', 'path/frontend/file.txt', $contents) ); // test several modules @@ -166,7 +166,7 @@ public function testLayoutGetDependencyInfo($contents, $type, $isHandle) ]; $model = $isHandle ? new LayoutRule([], [], $data) : new LayoutRule([], $data, []); $this->assertEquals( - [['module' => 'Magento\Theme', 'type' => $type, 'source' => 'any_handle_name']], + [['modules' => ['Magento\Theme'], 'type' => $type, 'source' => 'any_handle_name']], $model->getDependencyInfo('any', 'layout', 'path/frontend/file.txt', $contents) ); $this->assertEquals( diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/PhpRuleTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/PhpRuleTest.php index a636aa81800d1..d1350d1b54db9 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/PhpRuleTest.php +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Dependency/PhpRuleTest.php @@ -89,7 +89,7 @@ public function getDependencyInfoDataProvider() 'something extends \Magento\SomeModule\Any\ClassName {', [ [ - 'module' => 'Magento\SomeModule', + 'modules' => ['Magento\SomeModule'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'Magento\SomeModule\Any\ClassName', ] @@ -105,7 +105,7 @@ public function getDependencyInfoDataProvider() '$this->getViewFileUrl("Magento_SomeModule::js/order-by-sku-failure.js")', [ [ - 'module' => 'Magento\SomeModule', + 'modules' => ['Magento\SomeModule'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'Magento_SomeModule', ] @@ -121,7 +121,7 @@ public function getDependencyInfoDataProvider() '$this->helper("Magento\SomeModule\Any\ClassName")', [ [ - 'module' => 'Magento\SomeModule', + 'modules' => ['Magento\SomeModule'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'Magento\SomeModule\Any\ClassName', ] @@ -136,7 +136,7 @@ public function getDependencyInfoDataProvider() '$this->getLayout()->getBlock(\'block.name\');', [ [ - 'module' => 'Magento\SomeModule', + 'modules' => ['Magento\SomeModule'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'getBlock(\'block.name\')', ] @@ -157,7 +157,7 @@ public function getDependencyInfoDataProvider() 'Magento\Module2\Subject', [ [ - 'module' => 'Magento\Module2', + 'modules' => ['Magento\Module2'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_SOFT, 'source' => 'Magento\Module2\Subject', ] @@ -168,7 +168,7 @@ public function getDependencyInfoDataProvider() 'Magento\Module2\NotSubject', [ [ - 'module' => 'Magento\Module2', + 'modules' => ['Magento\Module2'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_SOFT, 'source' => 'Magento\Module2\NotSubject', ] @@ -179,7 +179,7 @@ public function getDependencyInfoDataProvider() 'Magento\OtherModule\NotSubject', [ [ - 'module' => 'Magento\OtherModule', + 'modules' => ['Magento\OtherModule'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'Magento\OtherModule\NotSubject', ] @@ -222,7 +222,7 @@ public function getDependencyInfoDataCaseGetUrlDataProvider() '$this->getUrl("cms/index/index")', [ [ - 'module' => 'Magento\Cms', + 'modules' => ['Magento\Cms'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'getUrl("cms/index/index"', ] @@ -295,7 +295,7 @@ public function getDefaultModelDependencyDataProvider() '$this->getLayout()->getBlock(\'block.name\');', [ [ - 'module' => 'Magento\SomeModule', + 'modules' => ['Magento\SomeModule'], 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD, 'source' => 'getBlock(\'block.name\')', ] diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php index c5447ef716eb2..c53586599ef00 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php @@ -306,6 +306,8 @@ private function assertClassNamespace(string $file, string $relativePath, string public function testClassReferences() { + $this->markTestSkipped("To be fixed in MC-33329. The test is not working properly " + . "after blacklisting logic was fixed. Previously it was ignoring all files."); $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( /** @@ -427,9 +429,9 @@ private function handleAliasClasses(array $aliasClasses, array $badClasses): arr private function referenceBlacklistFilter(array $classes): array { // exceptions made for the files from the blacklist - $classes = $this->getReferenceBlacklist(); + $blacklistClasses = $this->getReferenceBlacklist(); foreach ($classes as $class) { - if (in_array($class, $this->referenceBlackList)) { + if (in_array($class, $blacklistClasses)) { unset($classes[array_search($class, $classes)]); } } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php index 60855043a8c4e..302894c3cface 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/DependencyTest.php @@ -166,6 +166,21 @@ class DependencyTest extends \PHPUnit\Framework\TestCase */ private static $routeMapper = null; + /** + * @var ComponentRegistrar + */ + private static $componentRegistrar = null; + + /** + * @var array + */ + private $externalDependencyBlacklist; + + /** + * @var array + */ + private $undeclaredDependencyBlacklist; + /** * Sets up data * @@ -258,13 +273,11 @@ protected static function _initThemes() */ protected static function _initRules() { - $replaceFilePattern = str_replace('\\', '/', realpath(__DIR__)) - . '/_files/dependency_test/tables_*.php'; - $dbRuleTables = []; - foreach (glob($replaceFilePattern) as $fileName) { - //phpcs:ignore Magento2.Performance.ForeachArrayMerge - $dbRuleTables = array_merge($dbRuleTables, include $fileName); - } + $tableToPrimaryModuleMap= self::getTableToPrimaryModuleMap(); + $tableToAnyModuleMap = self::getTableToAnyModuleMap(); + // In case primary module declaring the table cannot be identified, use any module referencing this table + $tableToModuleMap = array_merge($tableToAnyModuleMap, $tableToPrimaryModuleMap); + self::$_rulesInstances = [ new PhpRule( self::$routeMapper->getRoutes(), @@ -272,14 +285,14 @@ protected static function _initRules() [], ['routes' => self::getRoutesWhitelist()] ), - new DbRule($dbRuleTables), + new DbRule($tableToModuleMap), new LayoutRule( self::$routeMapper->getRoutes(), self::$_mapLayoutBlocks, self::$_mapLayoutHandles ), new DiRule(new VirtualTypeMapper()), - new ReportsConfigRule($dbRuleTables), + new ReportsConfigRule($tableToModuleMap), new AnalyticsConfigRule(), ]; } @@ -303,6 +316,78 @@ private static function getRoutesWhitelist(): array return self::$routesWhitelist; } + /** + * Get full path to app/code directory, assuming these tests are run from the dev/tests directory. + * + * @return string + * @throws \LogicException + */ + private static function getAppCodeDir() + { + $appCode = BP . '/app/code'; + if (!$appCode) { + throw new \LogicException('app/code directory cannot be located'); + } + return $appCode; + } + + /** + * Get a map of tables to primary modules. + * + * Primary module is the one which initially defines the table (versus the module extending its declaration). + * + * @see getTableToAnyModuleMap + * + * @return array + */ + private static function getTableToPrimaryModuleMap(): array + { + $appCode = self::getAppCodeDir(); + $tableToPrimaryModuleMap = []; + foreach (glob($appCode . '/*/*/etc/db_schema_whitelist.json') as $file) { + $dbSchemaWhitelist = (array)json_decode(file_get_contents($file)); + preg_match('|.*/(.*)/(.*)/etc/db_schema_whitelist.json|', $file, $matches); + $moduleName = $matches[1] . '\\' . $matches[2]; + $isStagingModule = (substr_compare($moduleName, 'Staging', -strlen('Staging')) === 0); + if ($isStagingModule) { + // even though staging modules modify the constraints, they almost never declare new tables + continue; + } + foreach ($dbSchemaWhitelist as $tableName => $tableMetadata) { + if (isset($tableMetadata->constraint)) { + $tableToPrimaryModuleMap[$tableName] = $moduleName; + } + } + } + return $tableToPrimaryModuleMap; + } + + /** + * Get a map of tables matching to module names. + * + * Every table will have a module associated with it, + * even if the primary module cannot be defined based on declared constraints. + * + * @see getTableToPrimaryModuleMap + * + * @return array + */ + private static function getTableToAnyModuleMap(): array + { + $appCode = self::getAppCodeDir(); + $tableToAnyModuleMap = []; + foreach (glob($appCode . '/*/*/etc/db_schema_whitelist.json') as $file) { + $dbSchemaWhitelist = (array)json_decode(file_get_contents($file)); + $tables = array_keys($dbSchemaWhitelist); + preg_match('|.*/(.*)/(.*)/etc/db_schema_whitelist.json|', $file, $matches); + $moduleName = $matches[1] . '\\' . $matches[2]; + foreach ($tables as $table) { + $tableToAnyModuleMap[$table] = $moduleName; + } + } + return $tableToAnyModuleMap; + } + /** * Return cleaned file contents * @@ -353,6 +438,7 @@ function ($matches) use ($contents, &$contentsWithoutHtml) { public function testUndeclared() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); + $blackList = $this->getUndeclaredDependencyBlacklist(); $invoker( /** * Check undeclared modules dependencies for specified file @@ -360,27 +446,12 @@ public function testUndeclared() * @param string $fileType * @param string $file */ - function ($fileType, $file) { - // Validates file when it is belonged to default themes - $componentRegistrar = new ComponentRegistrar(); - foreach ($componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themeDir) { - if (strpos($file, $themeDir . '/') !== false) { - return; - } - } - - $foundModuleName = ''; - foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) { - if (strpos($file, $moduleDir . '/') !== false) { - $foundModuleName = str_replace('_', '\\', $moduleName); - break; - } - } - if (empty($foundModuleName)) { + function ($fileType, $file) use ($blackList) { + $module = $this->getModuleNameForRelevantFile($file); + if (!$module) { return; } - $module = $foundModuleName; $contents = $this->_getCleanedFileContents($fileType, $file); $dependencies = $this->getDependenciesFromFiles($module, $fileType, $file, $contents); @@ -390,7 +461,9 @@ function ($fileType, $file) { // Prepare output message $result = []; + foreach ($undeclaredDependency as $type => $modules) { + $modules = $this->filterOutBlacklistedDependencies($file, $modules, $blackList); $modules = array_unique($modules); if (empty($modules)) { continue; @@ -405,6 +478,180 @@ function ($fileType, $file) { ); } + /** + * Filter out list of module dependencies based on the provided blacklist. + * + * Always exclude dependency on Setup because it is part of base Magento package. + * + * @param string $filePath + * @param string[] $modules + * @param array $blackList + * @return string[] + */ + private function filterOutBlacklistedDependencies($filePath, $modules, array $blackList): array + { + $relativeFilePath = substr_replace($filePath, '', 0, strlen(BP . '/')); + foreach ($modules as $moduleKey => $module) { + if ($module == 'Magento\Setup') { + unset($modules[$moduleKey]); + } + if (isset($blackList[$relativeFilePath]) + && in_array($module, $blackList[$relativeFilePath]) + ) { + unset($modules[$moduleKey]); + } + } + return $modules; + } + + /** + * Identify dependencies on the components which are not part of the current project. + * + * For example, such test allows to prevent invalid dependencies from the storefront application to the monolith. + * + * @throws \Exception + */ + public function testExternalDependencies() + { + $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); + $blackList = $this->getExternalDependencyBlacklist(); + $invoker( + /** + * Check external modules dependencies for specified file + * + * @param string $fileType + * @param string $file + */ + function ($fileType, $file) use ($blackList) { + $module = $this->getModuleNameForRelevantFile($file); + if (!$module) { + return; + } + $externalDependencies = $this->collectExternalDependencies($file, $fileType, $module); + // Prepare output message + $result = []; + foreach ($externalDependencies as $type => $modules) { + $modules = $this->filterOutBlacklistedDependencies($file, $modules, $blackList); + $modules = array_unique($modules); + if (empty($modules)) { + continue; + } + $result[] = sprintf("%s [%s]", $type, implode(', ', $modules)); + } + if (!empty($result)) { + $this->fail('Module ' . $module . ' has external dependencies: ' . implode(', ', $result)); + } + }, + $this->getAllFiles() + ); + } + + /** + * Return module name for the file being tested if it should be tested. Return empty string otherwise. + * + * @param string $file + * @return string + */ + private function getModuleNameForRelevantFile($file) + { + if (!isset(self::$componentRegistrar)) { + self::$componentRegistrar = new ComponentRegistrar(); + } + // Validates file when it belongs to default themes + foreach (self::$componentRegistrar->getPaths(ComponentRegistrar::THEME) as $themeDir) { + if (strpos($file, $themeDir . '/') !== false) { + return ''; + } + } + + $foundModuleName = ''; + foreach (self::$componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) { + if (strpos($file, $moduleDir . '/') !== false) { + $foundModuleName = str_replace('_', '\\', $moduleName); + break; + } + } + if (empty($foundModuleName)) { + return ''; + } + + return $foundModuleName; + } + + /** + * Collect a list of external dependencies of the specified file. + * + * Dependency is considered external if it cannot be traced withing current codebase. + * + * @param string $file + * @param string $fileType + * @param string $module + * @return array + * @throws LocalizedException + */ + private function collectExternalDependencies($file, $fileType, $module) + { + $contents = $this->_getCleanedFileContents($fileType, $file); + + $dependencies = $this->getDependenciesFromFiles($module, $fileType, $file, $contents); + $externalDependencies = []; + foreach ($dependencies as $dependency) { + $dependencyModules = $dependency['modules']; + foreach ($dependencyModules as $dependencyModule) { + if ($dependency['type'] !== 'soft' + && !isset(self::$mapDependencies[$dependencyModule]) + && (strpos($dependencyModule, 'Magento\Framework') !== 0) + ) { + $dependencySummary = ($dependencyModule !== 'Unknown') + ? $dependencyModule + : $dependency['source']; + $externalDependencies[$dependency['type']][] = $dependencySummary; + } + } + } + return $externalDependencies; + } + + /** + * Return a list of blacklisted external dependencies. + * + * @return array + */ + private function getExternalDependencyBlacklist(): array + { + if (!isset($this->externalDependencyBlacklist)) { + $this->externalDependencyBlacklist = []; + foreach (glob(__DIR__ . '/_files/blacklist/external_dependency/*.php') as $filename) { + $this->externalDependencyBlacklist = array_merge_recursive( + $this->externalDependencyBlacklist, + include $filename + ); + } + } + + return $this->externalDependencyBlacklist; + } + + /** + * Return a list of blacklisted undeclared dependencies. + * + * @return array + */ + private function getUndeclaredDependencyBlacklist(): array + { + if (!isset($this->undeclaredDependencyBlacklist)) { + $this->undeclaredDependencyBlacklist = []; + foreach (glob(__DIR__ . '/_files/blacklist/undeclared_dependency/*.php') as $filename) { + $this->undeclaredDependencyBlacklist = array_merge_recursive( + $this->undeclaredDependencyBlacklist, + include $filename + ); + } + } + + return $this->undeclaredDependencyBlacklist; + } + /** * Retrieve dependencies from files * @@ -412,7 +659,14 @@ function ($fileType, $file) { * @param string $fileType * @param string $file * @param string $contents - * @return string[] + * @return array [ + * [ + * 'modules' => string[], + * 'type' => string + * 'source' => string + * ], + * ... + * ] * @throws LocalizedException */ protected function getDependenciesFromFiles($module, $fileType, $file, $contents) @@ -425,14 +679,20 @@ protected function getDependenciesFromFiles($module, $fileType, $file, $contents //phpcs:ignore Magento2.Performance.ForeachArrayMerge $dependencies = array_merge($dependencies, $newDependencies); } - foreach ($dependencies as $key => $dependency) { + + foreach ($dependencies as $dependencyKey => $dependency) { foreach (self::$whiteList as $namespace) { if (strpos($dependency['source'], $namespace) !== false) { - $dependency['module'] = $namespace; - $dependencies[$key] = $dependency; + $dependency['modules'] = [$namespace]; + $dependencies[$dependencyKey] = $dependency; } } + $dependency['type'] = $dependency['type'] ?? 'type is unknown'; + if (empty($dependency['modules'])) { + unset($dependencies[$dependencyKey]); + } } + return $dependencies; } @@ -471,20 +731,8 @@ private function collectDependency($dependency, $currentModule, &$undeclared) $declared = $type == self::TYPE_SOFT ? array_merge($soft, $hard) : $hard; - $module = $dependency['module']; - if (is_array($module)) { - $this->collectConditionalDependencies($module, $type, $currentModule, $declared, $undeclared); - } else { - $nsModule = str_replace('_', '\\', $module); - - if (!in_array($nsModule, $declared) && !$this->_isFake($nsModule)) { - $undeclared[$type][] = $module; - } elseif (in_array($nsModule, $declared) && $this->_isFake($nsModule)) { - $this->_setDependencies($currentModule, $type, self::MAP_TYPE_REDUNDANT, $module); - } - - $this->addDependency($currentModule, $type, self::MAP_TYPE_FOUND, $nsModule); - } + $modules = $dependency['modules']; + $this->collectConditionalDependencies($modules, $type, $currentModule, $declared, $undeclared); } /** @@ -746,6 +994,14 @@ protected static function convertModuleName(string $jsonName, array $packageModu return $moduleName; } + // convert names of the modules not registered in any composer.json + preg_match('|magento/module-(.*)|', $jsonName, $matches); + if (isset($matches[1])) { + $moduleNameHyphenated = $matches[1]; + $moduleNameUpperCamelCase = 'Magento\\' . str_replace('-', '', ucwords($moduleNameHyphenated, '-')); + return $moduleNameUpperCamelCase; + } + return $jsonName; } diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/external_dependency/ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/external_dependency/ce.php new file mode 100644 index 0000000000000..3330b5a941207 --- /dev/null +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/external_dependency/ce.php @@ -0,0 +1,10 @@ +<?php +/** + * Black list for the @see \Magento\Test\Integrity\DependencyTest::testExternalDependencies() + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +return [ + 'app/code/Magento/Paypal/Model/AbstractConfig.php' => ['Magento\Cart'], +]; diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/undeclared_dependency/ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/undeclared_dependency/ce.php new file mode 100644 index 0000000000000..3a8c59c07848b --- /dev/null +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/undeclared_dependency/ce.php @@ -0,0 +1,10 @@ +<?php +/** + * Black list for the @see \Magento\Test\Integrity\DependencyTest::testUndeclared() + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +return [ + 'app/code/Magento/Paypal/Model/AbstractConfig.php' => ['Magento\Cart'], +]; diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php deleted file mode 100644 index 3fb53be2ec400..0000000000000 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/dependency_test/tables_ce.php +++ /dev/null @@ -1,305 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -return [ - 'admin_assert' => 'Magento\Backend', - 'authorization_role' => 'Magento\Authorization', - 'authorization_rule' => 'Magento\Authorization', - 'admin_user' => 'Magento\User', - 'adminnotification_inbox' => 'Magento\AdminNotification', - 'catalog_category_entity_datetime' => 'Magento\Catalog', - 'catalog_category_entity_decimal' => 'Magento\Catalog', - 'catalog_category_entity_int' => 'Magento\Catalog', - 'catalog_category_entity_text' => 'Magento\Catalog', - 'catalog_category_entity_varchar' => 'Magento\Catalog', - 'catalog_product_entity_datetime' => 'Magento\Catalog', - 'catalog_product_entity_decimal' => 'Magento\Catalog', - 'catalog_product_entity_gallery' => 'Magento\Catalog', - 'catalog_product_entity_int' => 'Magento\Catalog', - 'catalog_product_entity_text' => 'Magento\Catalog', - 'catalog_product_entity_varchar' => 'Magento\Catalog', - 'catalog_product_bundle_option' => 'Magento\Bundle', - 'catalog_product_index_price_bundle_opt_idx' => 'Magento\Bundle', - 'catalog_product_index_price_bundle_opt_tmp' => 'Magento\Bundle', - 'catalog_product_bundle_option_value' => 'Magento\Bundle', - 'catalog_product_bundle_price_index' => 'Magento\Bundle', - 'catalog_product_index_price_bundle_idx' => 'Magento\Bundle', - 'catalog_product_index_price_bundle_tmp' => 'Magento\Bundle', - 'catalog_product_bundle_selection' => 'Magento\Bundle', - 'catalog_product_index_price_bundle_sel_idx' => 'Magento\Bundle', - 'catalog_product_index_price_bundle_sel_tmp' => 'Magento\Bundle', - 'catalog_product_bundle_selection_price' => 'Magento\Bundle', - 'catalog_product_bundle_stock_index' => 'Magento\Bundle', - 'captcha_log' => 'Magento\Captcha', - 'catalog_category_entity' => 'Magento\Catalog', - 'catalog_category_flat' => 'Magento\Catalog', - 'catalog_category_product' => 'Magento\Catalog', - 'catalog_category_product_index' => 'Magento\Catalog', - 'catalog_compare_item' => 'Magento\Catalog', - 'catalog_eav_attribute' => 'Magento\Catalog', - 'catalog_product_entity' => 'Magento\Catalog', - 'catalog_product_entity_media_gallery' => 'Magento\Catalog', - 'catalog_product_entity_media_gallery_value' => 'Magento\Catalog', - 'catalog_product_entity_tier_price' => 'Magento\Catalog', - 'catalog_product_index_eav_decimal_idx' => 'Magento\Catalog', - 'catalog_product_index_eav_decimal_tmp' => 'Magento\Catalog', - 'catalog_product_index_eav_idx' => 'Magento\Catalog', - 'catalog_product_index_eav_tmp' => 'Magento\Catalog', - 'catalog_product_flat' => 'Magento\Catalog', - 'catalog_product_index_eav' => 'Magento\Catalog', - 'catalog_product_index_eav_decimal' => 'Magento\Catalog', - 'catalog_product_index_price' => 'Magento\Catalog', - 'catalog_product_index_tier_price' => 'Magento\Catalog', - 'catalog_product_index_website' => 'Magento\Catalog', - 'catalog_product_link' => 'Magento\Catalog', - 'catalog_product_link_attribute' => 'Magento\Catalog', - 'catalog_product_link_attribute_decimal' => 'Magento\Catalog', - 'catalog_product_link_attribute_int' => 'Magento\Catalog', - 'catalog_product_link_attribute_varchar' => 'Magento\Catalog', - 'catalog_product_link_type' => 'Magento\Catalog', - 'catalog_product_option' => 'Magento\Catalog', - 'catalog_product_option_price' => 'Magento\Catalog', - 'catalog_product_option_title' => 'Magento\Catalog', - 'catalog_product_option_type_price' => 'Magento\Catalog', - 'catalog_product_option_type_title' => 'Magento\Catalog', - 'catalog_product_option_type_value' => 'Magento\Catalog', - 'catalog_product_index_price_cfg_opt_agr_idx' => 'Magento\Catalog', - 'catalog_product_index_price_cfg_opt_agr_tmp' => 'Magento\Catalog', - 'catalog_product_index_price_cfg_opt_idx' => 'Magento\Catalog', - 'catalog_product_index_price_cfg_opt_tmp' => 'Magento\Catalog', - 'catalog_product_index_price_final_idx' => 'Magento\Catalog', - 'catalog_product_index_price_final_tmp' => 'Magento\Catalog', - 'catalog_product_index_price_idx' => 'Magento\Catalog', - 'catalog_product_index_price_opt_agr_idx' => 'Magento\Catalog', - 'catalog_product_index_price_opt_agr_tmp' => 'Magento\Catalog', - 'catalog_product_index_price_opt_idx' => 'Magento\Catalog', - 'catalog_product_index_price_opt_tmp' => 'Magento\Catalog', - 'catalog_product_index_price_tmp' => 'Magento\Catalog', - 'catalog_product_relation' => 'Magento\Catalog', - 'catalog_product_super_attribute' => 'Magento\Catalog', - 'catalog_product_super_attribute_label' => 'Magento\Catalog', - 'catalog_product_super_attribute_pricing' => 'Magento\Catalog', - 'catalog_product_super_link' => 'Magento\Catalog', - 'catalog_product_website' => 'Magento\Catalog', - 'cataloginventory_stock' => 'Magento\CatalogInventory', - 'cataloginventory_stock_item' => 'Magento\CatalogInventory', - 'cataloginventory_stock_status' => 'Magento\CatalogInventory', - 'cataloginventory_stock_status_idx' => 'Magento\CatalogInventory', - 'cataloginventory_stock_status_tmp' => 'Magento\CatalogInventory', - 'catalogrule_customer_group' => 'Magento\CatalogRule', - 'catalogrule' => 'Magento\CatalogRule', - 'catalogrule_group_website' => 'Magento\CatalogRule', - 'catalogrule_product' => 'Magento\CatalogRule', - 'catalogrule_product_price' => 'Magento\CatalogRule', - 'catalogrule_website' => 'Magento\CatalogRule', - 'catalogsearch_fulltext' => 'Magento\CatalogSearch', - 'catalogsearch_result' => 'Magento\CatalogSearch', - 'search_query' => 'Magento\Search', - 'checkout_agreement' => 'Magento\Checkout', - 'checkout_agreement_store' => 'Magento\Checkout', - 'cms_block' => 'Magento\Cms', - 'cms_block_store' => 'Magento\Cms', - 'cms_page' => 'Magento\Cms', - 'cms_page_store' => 'Magento\Cms', - 'core_config_data' => 'Magento\Config', - 'design_change' => 'Magento\Theme', - 'media_storage_directory_storage' => 'Magento\MediaStorage', - 'email_template' => 'Magento\Email', - 'media_storage_file_storage' => 'Magento\MediaStorage', - 'store' => 'Magento\Store', - 'store_group' => 'Magento\Store', - 'store_website' => 'Magento\Store', - 'cron_schedule' => 'Magento\Cron', - 'customer_address_entity' => 'Magento\Customer', - 'customer_group' => 'Magento\Customer', - 'customer_eav_attribute' => 'Magento\Customer', - 'customer_eav_attribute_website' => 'Magento\Customer', - 'customer_entity' => 'Magento\Customer', - 'customer_form_attribute' => 'Magento\Customer', - 'customer_address_entity_datetime' => 'Magento\Customer', - 'customer_address_entity_decimal' => 'Magento\Customer', - 'customer_address_entity_int' => 'Magento\Customer', - 'customer_address_entity_text' => 'Magento\Customer', - 'customer_address_entity_varchar' => 'Magento\Customer', - 'customer_entity_datetime' => 'Magento\Customer', - 'customer_entity_decimal' => 'Magento\Customer', - 'customer_entity_int' => 'Magento\Customer', - 'customer_entity_text' => 'Magento\Customer', - 'customer_entity_varchar' => 'Magento\Customer', - 'customer_visitor' => 'Magento\Customer', - 'directory_country' => 'Magento\Directory', - 'directory_country_format' => 'Magento\Directory', - 'directory_country_name' => 'Magento\Directory', - 'directory_country_region' => 'Magento\Directory', - 'directory_country_region_name' => 'Magento\Directory', - 'directory_currency_rate' => 'Magento\Directory', - 'downloadable_link' => 'Magento\Downloadable', - 'downloadable_link_price' => 'Magento\Downloadable', - 'downloadable_link_purchased' => 'Magento\Downloadable', - 'downloadable_link_purchased_item' => 'Magento\Downloadable', - 'downloadable_link_title' => 'Magento\Downloadable', - 'catalog_product_index_price_downlod_idx' => 'Magento\Downloadable', - 'catalog_product_index_price_downlod_tmp' => 'Magento\Downloadable', - 'downloadable_sample' => 'Magento\Downloadable', - 'downloadable_sample_title' => 'Magento\Downloadable', - 'eav_attribute' => 'Magento\Eav', - 'eav_attribute_group' => 'Magento\Eav', - 'eav_attribute_label' => 'Magento\Eav', - 'eav_attribute_option' => 'Magento\Eav', - 'eav_attribute_option_value' => 'Magento\Eav', - 'eav_attribute_set' => 'Magento\Eav', - 'eav_entity' => 'Magento\Eav', - 'eav_entity_attribute' => 'Magento\Eav', - 'eav_entity_attribute_source_table' => 'Magento\Eav', - 'eav_entity_store' => 'Magento\Eav', - 'eav_entity_type' => 'Magento\Eav', - 'eav_form_element' => 'Magento\Eav', - 'eav_form_fieldset' => 'Magento\Eav', - 'eav_form_fieldset_label' => 'Magento\Eav', - 'eav_form_type' => 'Magento\Eav', - 'eav_form_type_entity' => 'Magento\Eav', - 'eav_entity_datetime' => 'Magento\Eav', - 'eav_entity_decimal' => 'Magento\Eav', - 'eav_entity_int' => 'Magento\Eav', - 'eav_entity_text' => 'Magento\Eav', - 'eav_entity_varchar' => 'Magento\Eav', - 'find_feed_import_codes' => 'Find\Feed', - 'gift_message' => 'Magento\GiftMessage', - 'googleoptimizer_code' => 'Magento\GoogleOptimizer', - 'importexport_importdata' => 'Magento\ImportExport', - 'integration' => 'Magento\Integration', - 'layout_link' => 'Magento\Widget', - 'layout_update' => 'Magento\Widget', - 'log_customer' => 'Magento\Log', - 'log_quote' => 'Magento\Log', - 'log_summary' => 'Magento\Log', - 'log_summary_type' => 'Magento\Log', - 'log_url_info' => 'Magento\Log', - 'log_url' => 'Magento\Log', - 'log_visitor' => 'Magento\Log', - 'log_visitor_info' => 'Magento\Log', - 'log_visitor_online' => 'Magento\Log', - 'newsletter_problem' => 'Magento\Newsletter', - 'newsletter_queue' => 'Magento\Newsletter', - 'newsletter_queue_link' => 'Magento\Newsletter', - 'newsletter_queue_store_link' => 'Magento\Newsletter', - 'newsletter_subscriber' => 'Magento\Newsletter', - 'newsletter_template' => 'Magento\Newsletter', - 'oauth_consumer' => 'Magento\Integration', - 'oauth_nonce' => 'Magento\Integration', - 'oauth_token' => 'Magento\Integration', - 'authorizenet_debug' => 'Magento\Authorizenet', - 'admin_passwords' => 'Magento\User', - 'paypal_cert' => 'Magento\Paypal', - 'paypal_payment_transaction' => 'Magento\Paypal', - 'paypal_settlement_report' => 'Magento\Paypal', - 'paypal_settlement_report_row' => 'Magento\Paypal', - 'persistent_session' => 'Magento\Persistent', - 'product_alert_price' => 'Magento\ProductAlert', - 'product_alert_stock' => 'Magento\ProductAlert', - 'rating' => 'Magento\Review', - 'rating_entity' => 'Magento\Review', - 'rating_option' => 'Magento\Review', - 'rating_option_vote' => 'Magento\Review', - 'rating_store' => 'Magento\Review', - 'rating_title' => 'Magento\Review', - 'rating_option_vote_aggregated' => 'Magento\Review', - 'report_compared_product_index' => 'Magento\Reports', - 'report_event' => 'Magento\Reports', - 'report_event_types' => 'Magento\Reports', - 'report_viewed_product_index' => 'Magento\Reports', - 'review' => 'Magento\Review', - 'review_entity_summary' => 'Magento\Review', - 'review_detail' => 'Magento\Review', - 'review_entity' => 'Magento\Review', - 'review_status' => 'Magento\Review', - 'review_store' => 'Magento\Review', - 'sales_bestsellers_aggregated_daily' => 'Magento\Sales', - 'sales_bestsellers_aggregated_monthly' => 'Magento\Sales', - 'sales_bestsellers_aggregated_yearly' => 'Magento\Sales', - 'paypal_billing_agreement' => 'Magento\Paypal', - 'paypal_billing_agreement_order' => 'Magento\Paypal', - 'sales_creditmemo' => 'Magento\Sales', - 'sales_creditmemo_comment' => 'Magento\Sales', - 'sales_creditmemo_grid' => 'Magento\Sales', - 'sales_creditmemo_item' => 'Magento\Sales', - 'sales_invoice' => 'Magento\Sales', - 'sales_invoice_comment' => 'Magento\Sales', - 'sales_invoice_grid' => 'Magento\Sales', - 'sales_invoice_item' => 'Magento\Sales', - 'sales_invoiced_aggregated' => 'Magento\Sales', - 'sales_invoiced_aggregated_order' => 'Magento\Sales', - 'sales_order' => 'Magento\Sales', - 'sales_order_address' => 'Magento\Sales', - 'sales_order_aggregated_created' => 'Magento\Sales', - 'sales_order_aggregated_updated' => 'Magento\Sales', - 'sales_order_grid' => 'Magento\Sales', - 'sales_order_item' => 'Magento\Sales', - 'sales_order_item_option' => 'Magento\Sales', - 'sales_order_payment' => 'Magento\Sales', - 'sales_order_status' => 'Magento\Sales', - 'sales_order_status_history' => 'Magento\Sales', - 'sales_order_status_label' => 'Magento\Sales', - 'sales_order_status_state' => 'Magento\Sales', - 'sales_order_tax' => 'Magento\Tax', - 'sales_payment_transaction' => 'Magento\Sales', - 'quote' => 'Magento\Quote', - 'quote_address' => 'Magento\Quote', - 'quote_address_item' => 'Magento\Quote', - 'quote_shipping_rate' => 'Magento\Quote', - 'quote_item' => 'Magento\Quote', - 'quote_item_option' => 'Magento\Quote', - 'quote_payment' => 'Magento\Quote', - 'sales_refunded_aggregated' => 'Magento\Sales', - 'sales_refunded_aggregated_order' => 'Magento\Sales', - 'sales_shipment' => 'Magento\Sales', - 'sales_shipment_comment' => 'Magento\Sales', - 'sales_shipment_grid' => 'Magento\Sales', - 'sales_shipment_item' => 'Magento\Sales', - 'sales_shipment_track' => 'Magento\Sales', - 'sales_shipping_aggregated' => 'Magento\Sales', - 'sales_shipping_aggregated_order' => 'Magento\Sales', - 'quote_entity' => 'Magento\Quote', - 'quote_temp' => 'Magento\Quote', - 'salesrule_coupon' => 'Magento\SalesRule', - 'coupon_aggregated' => 'Magento\SalesRule', - 'coupon_aggregated_order' => 'Magento\SalesRule', - 'coupon_aggregated_updated' => 'Magento\SalesRule', - 'salesrule_coupon_usage' => 'Magento\SalesRule', - 'salesrule_website' => 'Magento\SalesRule', - 'salesrule_label' => 'Magento\SalesRule', - 'salesrule_product_attribute' => 'Magento\SalesRule', - 'salesrule' => 'Magento\SalesRule', - 'salesrule_customer' => 'Magento\SalesRule', - 'salesrule_customer_group' => 'Magento\SalesRule', - 'sendfriend_log' => 'Magento\sendfriend', - 'shipping_tablerate' => 'Magento\shipping', - 'sitemap' => 'Magento\Sitemap', - 'social_facebook_actions' => 'Social\Facebook', - 'sales_order_tax_item' => 'Magento\Tax', - 'tax_calculation' => 'Magento\Tax', - 'tax_calculation_rate' => 'Magento\Tax', - 'tax_calculation_rate_title' => 'Magento\Tax', - 'tax_calculation_rule' => 'Magento\Tax', - 'tax_class' => 'Magento\Tax', - 'tax_order_aggregated_created' => 'Magento\Tax', - 'tax_order_aggregated_updated' => 'Magento\Tax', - 'translation' => 'Magento\Translation', - 'weee_tax' => 'Magento\Weee', - 'widget' => 'Magento\Widget', - 'widget_instance' => 'Magento\Widget', - 'widget_instance_page' => 'Magento\Widget', - 'widget_instance_page_layout' => 'Magento\Widget', - 'wishlist_item' => 'Magento\Wishlist', - 'wishlist_item_option' => 'Magento\Wishlist', - 'wishlist' => 'Magento\Wishlist', - 'admin_system_messages' => 'Magento\AdminNotification', - 'theme' => 'Magento\Theme', - 'theme_files' => 'Magento\Theme', - 'variable' => 'Magento\Variable', - 'variable_value' => 'Magento\Variable', - 'job_queue' => 'Magento\Queue', - 'catalogsearch_recommendations' => 'Magento\AdvancedSearch', -]; diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt index 181ecd43ce564..a143424feb015 100644 --- a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt +++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt @@ -2,7 +2,6 @@ app/code/Magento/Customer/view/frontend/web/js/zxcvbn.js app/code/Magento/Swagger/view/frontend/web/swagger-ui/js/swagger-ui-bundle.js app/code/Magento/Swagger/view/frontend/web/swagger-ui/js/swagger-ui-standalone-preset.js app/code/Magento/Tinymce3/view/base/web/tiny_mce/**/*.js -app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js app/code/Magento/Rule/view/adminhtml/web/rules.js app/code/Magento/Sales/view/adminhtml/web/order/create/giftmessage.js diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index 78bcec7abda09..99f27bec1bb57 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -4254,5 +4254,7 @@ ['Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapperProxy'], ['Magento\Elasticsearch\Elasticsearch5\Model\Adapter\DataMapper\ProductDataMapper'], ['Magento\Elasticsearch\Model\Adapter\DataMapper\DataMapperResolver'], - ['Magento\Elasticsearch\Model\Adapter\Container\Attribute'] + ['Magento\Elasticsearch\Model\Adapter\Container\Attribute'], + ['PHPUnit_Framework_MockObject_MockObject', 'PHPUnit\Framework\MockObject\MockObject'], + ['PHPUnit\Framework\BaseTestListener'], ]; diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php index 168ac5cde16cb..2849e61c0208c 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php @@ -202,4 +202,8 @@ ['Magento\BulkOperations', 'Magento\AsynchronousOperations'], ['Zend', 'Laminas'], ['Magento\Signifyd'], + ['Magento\Authorizenet'], + ['Magento\AuthorizenetAcceptjs'], + ['Magento\AuthorizenetCardinal'], + ['Magento\AuthorizenetGraphQl'], ]; diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt index 411f02e2c5930..fc8c0c17447d8 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt @@ -1,5 +1,4 @@ Magento/Adminhtml -Magento/Authorizenet/Model Magento/Backend Magento/Bundle Magento/Catalog/Block/Product/ProductList diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt index f54defbd57604..d153593a5ed4f 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpstan/blacklist/common.txt @@ -5,6 +5,7 @@ # dev/tests/static/framework/bootstrap.php lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php lib/internal/Magento/Framework/Cache/Backend/Eaccelerator.php +lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php dev/tests/integration/framework/deployTestModules.php dev/tests/integration/testsuite/Magento/Framework/Session/ConfigTest.php dev/tests/integration/testsuite/Magento/Framework/Session/SessionManagerTest.php diff --git a/lib/internal/Magento/Framework/Api/AbstractSimpleObjectBuilder.php b/lib/internal/Magento/Framework/Api/AbstractSimpleObjectBuilder.php index d9a972ac237f5..029a78bf0ddf7 100644 --- a/lib/internal/Magento/Framework/Api/AbstractSimpleObjectBuilder.php +++ b/lib/internal/Magento/Framework/Api/AbstractSimpleObjectBuilder.php @@ -3,10 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Api; /** * Base Builder Class for simple data Objects + * @deprecated Every builder should have their own implementation of \Magento\Framework\Api\SimpleBuilderInterface * @SuppressWarnings(PHPMD.NumberOfChildren) */ abstract class AbstractSimpleObjectBuilder implements SimpleBuilderInterface @@ -44,6 +47,8 @@ public function create() } /** + * Overwrite data in Object. + * * @param string $key * @param mixed $value * @@ -62,9 +67,12 @@ protected function _set($key, $value) */ protected function _getDataObjectType() { - $currentClass = get_class($this); - $builderSuffix = 'Builder'; - $dataObjectType = substr($currentClass, 0, -strlen($builderSuffix)); + $dataObjectType = ''; + $pattern = '/(?<data_object>.*?)Builder(\\Interceptor)?/'; + if (preg_match($pattern, get_class($this), $match)) { + $dataObjectType = $match['data_object']; + } + return $dataObjectType; } diff --git a/lib/internal/Magento/Framework/App/DeploymentConfig.php b/lib/internal/Magento/Framework/App/DeploymentConfig.php index ddd7faa80b906..6aeec2c2d0192 100644 --- a/lib/internal/Magento/Framework/App/DeploymentConfig.php +++ b/lib/internal/Magento/Framework/App/DeploymentConfig.php @@ -15,6 +15,7 @@ * Application deployment configuration * * @api + * @since 100.0.2 */ class DeploymentConfig { @@ -148,7 +149,7 @@ public function isDbAvailable() */ private function load() { - if (null === $this->data) { + if (empty($this->data)) { $this->data = $this->reader->load(); if ($this->overrideData) { $this->data = array_replace($this->data, $this->overrideData); @@ -183,6 +184,7 @@ private function flattenParams(array $params, $path = null, array &$flattenResul $newPath = $key; } if (isset($flattenResult[$newPath])) { + //phpcs:ignore Magento2.Exceptions.DirectThrow throw new RuntimeException(new Phrase("Key collision '%1' is already defined.", [$newPath])); } $flattenResult[$newPath] = $param; diff --git a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php index 81a4f842bdf1d..f93153f3cd75c 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php @@ -6,10 +6,12 @@ namespace Magento\Framework\App\Test\Unit; -use \Magento\Framework\App\DeploymentConfig; -use \Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\Config\ConfigOptionsListConstants; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class DeploymentConfigTest extends \PHPUnit\Framework\TestCase +class DeploymentConfigTest extends TestCase { /** * @var array @@ -63,7 +65,7 @@ class DeploymentConfigTest extends \PHPUnit\Framework\TestCase protected $_deploymentConfigMerged; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $reader; @@ -124,7 +126,7 @@ public function testNotAvailable(): void */ public function testNotAvailableThenAvailable(): void { - $this->reader->expects($this->once())->method('load')->willReturn([]); + $this->reader->expects($this->once())->method('load')->willReturn(['Test']); $object = new DeploymentConfig($this->reader); $this->assertFalse($object->isAvailable()); $this->assertFalse($object->isAvailable()); diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php index ec2731c667ee6..80d8808ab1768 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php +++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php @@ -13,6 +13,7 @@ use Magento\Framework\DB\Adapter\DeadlockException; use Magento\Framework\DB\Adapter\DuplicateException; use Magento\Framework\DB\Adapter\LockWaitException; +use Magento\Framework\DB\Adapter\TableNotFoundException; use Magento\Framework\DB\Ddl\Table; use Magento\Framework\DB\ExpressionConverter; use Magento\Framework\DB\LoggerInterface; @@ -38,6 +39,7 @@ * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @since 100.0.2 */ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface { @@ -257,6 +259,8 @@ public function __construct( 1213 => DeadlockException::class, // SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 1062 => DuplicateException::class, + // SQLSTATE[42S02]: Base table or view not found: 1146 + 1146 => TableNotFoundException::class, ]; try { parent::__construct($config); @@ -687,7 +691,8 @@ public function proccessBindCallback($matches) if (isset($matches[6]) && ( strpos($matches[6], "'") !== false || strpos($matches[6], ':') !== false || - strpos($matches[6], '?') !== false) + strpos($matches[6], '?') !== false + ) ) { $bindName = ':_mage_bind_var_' . (++$this->_bindIncrement); $this->_bindParams[$bindName] = $this->_unQuote($matches[6]); @@ -1822,7 +1827,7 @@ public function modifyColumnByDdl($tableName, $columnName, $definition, $flushDa * Retrieve column data type by data from describe table * * @param array $column - * @return string + * @return string|null * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function _getColumnTypeByDdl($column) @@ -1862,6 +1867,7 @@ protected function _getColumnTypeByDdl($column) case 'numeric': return Table::TYPE_DECIMAL; } + return null; } /** @@ -4020,6 +4026,7 @@ public function getAutoIncrementField($tableName, $schemaName = null) * Required to listen all DDL changes done by 3-rd party modules with old Install/UpgradeSchema scripts. * * @return SchemaListener + * @since 102.0.0 */ public function getSchemaListener() { @@ -4031,6 +4038,8 @@ public function getSchemaListener() /** * Closes the connection. + * + * @since 102.0.4 */ public function closeConnection() { diff --git a/lib/internal/Magento/Framework/DB/Adapter/TableNotFoundException.php b/lib/internal/Magento/Framework/DB/Adapter/TableNotFoundException.php new file mode 100644 index 0000000000000..7fded1fa01e91 --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Adapter/TableNotFoundException.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\DB\Adapter; + +/** + * Database base table or view not found exception + */ +class TableNotFoundException extends \Zend_Db_Adapter_Exception +{ +} diff --git a/lib/internal/Magento/Framework/DB/Select.php b/lib/internal/Magento/Framework/DB/Select.php index ceeed40787123..075aa6b24faa7 100644 --- a/lib/internal/Magento/Framework/DB/Select.php +++ b/lib/internal/Magento/Framework/DB/Select.php @@ -91,6 +91,12 @@ public function __construct( * $select->where('id = :id'); * </code> * + * You may also construct IN statements: + * + * <code> + * $select->where('entity_id IN (?)', ['1', '2', '3']); + * </code> + * * Note that it is more correct to use named bindings in your * queries for values other than strings. When you use named * bindings, don't forget to pass the values when actually @@ -101,7 +107,7 @@ public function __construct( * </code> * * @param string $cond The WHERE condition. - * @param string $value OPTIONAL A single value to quote into the condition. + * @param string|array|null $value OPTIONAL An optional single or array value to quote into the condition. * @param string|int|null $type OPTIONAL The type of the given value * @return \Magento\Framework\DB\Select */ diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index c497c4de5a5e4..7c9cf02ac6a47 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -6,7 +6,10 @@ namespace Magento\Framework\Data; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Data\Collection\EntityFactoryInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Exception\AlreadyExistsException; use Magento\Framework\Option\ArrayInterface; /** @@ -25,7 +28,7 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll /** * Collection items * - * @var \Magento\Framework\DataObject[] + * @var DataObject[] */ protected $_items = []; @@ -34,7 +37,7 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll * * @var string */ - protected $_itemObjectClass = \Magento\Framework\DataObject::class; + protected $_itemObjectClass = DataObject::class; /** * Order configuration @@ -46,7 +49,7 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll /** * Filters configuration * - * @var \Magento\Framework\DataObject[] + * @var DataObject[] */ protected $_filters = []; @@ -117,7 +120,7 @@ public function __construct(EntityFactoryInterface $entityFactory) */ public function addFilter($field, $value, $type = 'and') { - $filter = new \Magento\Framework\DataObject(); + $filter = new DataObject(); // implements ArrayAccess $filter['field'] = $field; $filter['value'] = $value; @@ -163,9 +166,9 @@ public function addFilter($field, $value, $type = 'and') * * @param string|array $field * @param string|int|array $condition - * @throws \Magento\Framework\Exception\LocalizedException if some error in the input could be detected. * @return $this * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @throws \Magento\Framework\Exception\LocalizedException if some error in the input could be detected. */ public function addFieldToFilter($field, $condition) { @@ -182,7 +185,7 @@ public function addFieldToFilter($field, $condition) * - array() -- get all filters * * @param string|string[] $field - * @return \Magento\Framework\DataObject|\Magento\Framework\DataObject[]|void + * @return DataObject|DataObject[]|void */ public function getFilter($field) { @@ -234,18 +237,16 @@ protected function _setIsLoaded($flag = true) /** * Get current collection page * - * @param int $displacement + * @param int $displacement * @return int */ public function getCurPage($displacement = 0) { if ($this->_curPage + $displacement < 1) { return 1; - } elseif ($this->_curPage + $displacement > $this->getLastPageNumber()) { - return $this->getLastPageNumber(); - } else { - return $this->_curPage + $displacement; } + + return $this->_curPage + $displacement; } /** @@ -260,9 +261,9 @@ public function getLastPageNumber() return 1; } elseif ($this->_pageSize) { return (int)ceil($collectionSize / $this->_pageSize); - } else { - return 1; } + + return 1; } /** @@ -292,7 +293,7 @@ public function getSize() /** * Retrieve collection first item * - * @return \Magento\Framework\DataObject + * @return DataObject */ public function getFirstItem() { @@ -309,7 +310,7 @@ public function getFirstItem() /** * Retrieve collection last item * - * @return \Magento\Framework\DataObject + * @return DataObject */ public function getLastItem() { @@ -325,7 +326,7 @@ public function getLastItem() /** * Retrieve collection items * - * @return \Magento\Framework\DataObject[] + * @return DataObject[] */ public function getItems() { @@ -336,8 +337,8 @@ public function getItems() /** * Retrieve field values from all items * - * @param string $colName - * @return array + * @param string $colName + * @return array */ public function getColumnValues($colName) { @@ -353,9 +354,9 @@ public function getColumnValues($colName) /** * Search all items by field value * - * @param string $column - * @param mixed $value - * @return array + * @param string $column + * @param array $value + * @return array */ public function getItemsByColumnValue($column, $value) { @@ -373,9 +374,9 @@ public function getItemsByColumnValue($column, $value) /** * Search first item by field value * - * @param string $column - * @param mixed $value - * @return \Magento\Framework\DataObject || null + * @param string $column + * @param string|int $value + * @return DataObject|null */ public function getItemByColumnValue($column, $value) { @@ -392,11 +393,11 @@ public function getItemByColumnValue($column, $value) /** * Adding item to item array * - * @param \Magento\Framework\DataObject $item + * @param DataObject $item * @return $this * @throws \Exception */ - public function addItem(\Magento\Framework\DataObject $item) + public function addItem(DataObject $item) { $itemId = $this->_getItemId($item); @@ -417,7 +418,7 @@ public function addItem(\Magento\Framework\DataObject $item) /** * Add item that has no id to collection * - * @param \Magento\Framework\DataObject $item + * @param DataObject $item * @return $this */ protected function _addItem($item) @@ -429,10 +430,10 @@ protected function _addItem($item) /** * Retrieve item id * - * @param \Magento\Framework\DataObject $item - * @return mixed + * @param DataObject $item + * @return string|int */ - protected function _getItemId(\Magento\Framework\DataObject $item) + protected function _getItemId(DataObject $item) { return $item->getId(); } @@ -454,7 +455,7 @@ public function getAllIds() /** * Remove item from collection by item key * - * @param mixed $key + * @param string $key * @return $this */ public function removeItemByKey($key) @@ -542,8 +543,8 @@ public function each($objMethod, $args = []) /** * Setting data for all collection items * - * @param mixed $key - * @param mixed $value + * @param string $key + * @param string|int|null $value * @return $this */ public function setDataToAll($key, $value = null) @@ -606,7 +607,7 @@ public function setOrder($field, $direction = self::SORT_ORDER_DESC) */ public function setItemObjectClass($className) { - if (!is_a($className, \Magento\Framework\DataObject::class, true)) { + if (!is_a($className, DataObject::class, true)) { throw new \InvalidArgumentException($className . ' does not extend \Magento\Framework\DataObject'); } $this->_itemObjectClass = $className; @@ -616,7 +617,7 @@ public function setItemObjectClass($className) /** * Retrieve collection empty item * - * @return \Magento\Framework\DataObject + * @return DataObject */ public function getNewEmptyItem() { @@ -748,8 +749,8 @@ public function toArray($arrRequiredFields = []) * Return items array * array( * $index => array( - * 'value' => mixed - * 'label' => mixed + * 'value' => string + * 'label' => string * ) * ) * @@ -815,8 +816,8 @@ protected function _toOptionHash($valueField = 'id', $labelField = 'name') /** * Retrieve item by id * - * @param mixed $idValue - * @return \Magento\Framework\DataObject + * @param string|int $idValue + * @return DataObject */ public function getItemById($idValue) { @@ -910,7 +911,7 @@ public function __sleep() */ public function __wakeup() { - $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $objectManager = ObjectManager::getInstance(); $this->_entityFactory = $objectManager->get(EntityFactoryInterface::class); } } diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php index b06f2f9e62397..8b983809e643f 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php +++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php @@ -24,8 +24,9 @@ abstract class AbstractAdapter implements AdapterInterface */ public $imageBackgroundColor = 0; - /** - * Position constants + /**#@+ + * Position constants. + * Used mainly for watermarks */ const POSITION_TOP_LEFT = 'top-left'; @@ -40,9 +41,10 @@ abstract class AbstractAdapter implements AdapterInterface const POSITION_TILE = 'tile'; const POSITION_CENTER = 'center'; + /**#@-*/ /** - * Default font size + * The size of the font to use as default */ const DEFAULT_FONT_SIZE = 15; diff --git a/lib/internal/Magento/Framework/Image/Adapter/AdapterInterface.php b/lib/internal/Magento/Framework/Image/Adapter/AdapterInterface.php index b31ed5c773495..a981df9d9fddc 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/AdapterInterface.php +++ b/lib/internal/Magento/Framework/Image/Adapter/AdapterInterface.php @@ -28,6 +28,8 @@ interface AdapterInterface public function getColorAt($x, $y); /** + * Render image and return its binary contents + * * @see \Magento\Framework\Image\Adapter\AbstractAdapter::getImage * @return string */ @@ -99,6 +101,7 @@ public function crop($top = 0, $left = 0, $right = 0, $bottom = 0); /** * Save image to specific path. + * * If some folders of path does not exist they will be created * * @param null|string $destination diff --git a/lib/internal/Magento/Framework/Image/Adapter/Config.php b/lib/internal/Magento/Framework/Image/Adapter/Config.php index 636bbcdcbdb41..d4a28b4efc600 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Config.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Config.php @@ -18,13 +18,13 @@ class Config implements ConfigInterface, UploadConfigInterface /** * Config path for the maximal image width value - * @deprecated + * @deprecated Used in a method that is deprecated */ const XML_PATH_MAX_WIDTH_IMAGE = 'system/upload_configuration/max_width'; /** * Config path for the maximal image height value - * @deprecated + * @deprecated Used in a method that is deprecated */ const XML_PATH_MAX_HEIGHT_IMAGE = 'system/upload_configuration/max_height'; diff --git a/lib/internal/Magento/Framework/Image/Adapter/ConfigInterface.php b/lib/internal/Magento/Framework/Image/Adapter/ConfigInterface.php index dab642b14ac6c..aa014b61e867a 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/ConfigInterface.php +++ b/lib/internal/Magento/Framework/Image/Adapter/ConfigInterface.php @@ -12,11 +12,15 @@ interface ConfigInterface { /** + * Get adapter alias + * * @return string */ public function getAdapterAlias(); /** + * Get adapters + * * @return array */ public function getAdapters(); diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index 6a7a11846334d..5cb968b1e5441 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -11,7 +11,7 @@ * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ -class Gd2 extends \Magento\Framework\Image\Adapter\AbstractAdapter +class Gd2 extends AbstractAdapter { /** * Required extensions diff --git a/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php b/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php index cd49f283d33a7..24e036c02e718 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php +++ b/lib/internal/Magento/Framework/Image/Adapter/ImageMagick.php @@ -5,7 +5,12 @@ */ namespace Magento\Framework\Image\Adapter; -class ImageMagick extends \Magento\Framework\Image\Adapter\AbstractAdapter +use Magento\Framework\Exception\LocalizedException; + +/** + * Image adapter from ImageMagick + */ +class ImageMagick extends AbstractAdapter { /** * The blur factor where > 1 is blurry, < 1 is sharp @@ -66,7 +71,7 @@ public function backgroundColor($color = null) * * @param string $filename * @return void - * @throws \Exception + * @throws \Magento\Framework\Exception\LocalizedException */ public function open($filename) { @@ -77,7 +82,11 @@ public function open($filename) try { $this->_imageHandler = new \Imagick($this->_fileName); } catch (\ImagickException $e) { - throw new \Exception(sprintf('Unsupported image format. File: %s', $this->_fileName), $e->getCode(), $e); + throw new LocalizedException( + __('Unsupported image format. File: %1', $this->_fileName), + $e, + $e->getCode() + ); } $this->backgroundColor(); @@ -86,12 +95,13 @@ public function open($filename) /** * Save image to specific path. + * * If some folders of path does not exist they will be created * * @param null|string $destination * @param null|string $newName * @return void - * @throws \Exception If destination path is not writable + * @throws \Magento\Framework\Exception\LocalizedException If destination path is not writable */ public function save($destination = null, $newName = null) { @@ -124,6 +134,8 @@ protected function _applyOptions() } /** + * Render image and return its binary contents + * * @see \Magento\Framework\Image\Adapter\AbstractAdapter::getImage * @return string */ @@ -241,7 +253,7 @@ public function crop($top = 0, $left = 0, $right = 0, $bottom = 0) * @param bool $tile * @return void * @throws \LogicException - * @throws \Exception + * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ @@ -253,28 +265,12 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity = $this->_checkCanProcess(); $opacity = $this->getWatermarkImageOpacity() ? $this->getWatermarkImageOpacity() : $opacity; - $opacity = (double)number_format($opacity / 100, 1); - $watermark = new \Imagick($imagePath); - if ($this->getWatermarkWidth() && - $this->getWatermarkHeight() && - $this->getWatermarkPosition() != self::POSITION_STRETCH - ) { - $watermark->resizeImage( - $this->getWatermarkWidth(), - $this->getWatermarkHeight(), - \Imagick::FILTER_CUBIC, - self::BLUR_FACTOR - ); - } + $watermark = new \Imagick($imagePath); - if (method_exists($watermark, 'getImageAlphaChannel')) { - // available from imagick 6.4.0 - if ($watermark->getImageAlphaChannel() == 0) { - $watermark->setImageAlphaChannel(\Imagick::ALPHACHANNEL_OPAQUE); - } - } + $this->resizeWatermark($watermark); + $this->handleWatermarkAlphaChannel($watermark); $compositeChannels = \Imagick::CHANNEL_ALL; $watermark->evaluateImage(\Imagick::EVALUATE_MULTIPLY, $opacity, \Imagick::CHANNEL_OPACITY); @@ -307,33 +303,16 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity = try { if ($tile) { - $offsetX = $positionX; - $offsetY = $positionY; - while ($offsetY <= $this->_imageSrcHeight + $watermark->getImageHeight()) { - while ($offsetX <= $this->_imageSrcWidth + $watermark->getImageWidth()) { - $this->_imageHandler->compositeImage( - $watermark, - \Imagick::COMPOSITE_OVER, - $offsetX, - $offsetY, - $compositeChannels - ); - $offsetX += $watermark->getImageWidth(); - } - $offsetX = $positionX; - $offsetY += $watermark->getImageHeight(); - } + $this->addTiledWatermark($positionX, $positionY, $watermark, $compositeChannels); } else { - $this->_imageHandler->compositeImage( - $watermark, - \Imagick::COMPOSITE_OVER, - $positionX, - $positionY, - $compositeChannels - ); + $this->addSingleWatermark($positionX, $positionY, $watermark, $compositeChannels); } } catch (\ImagickException $e) { - throw new \Exception('Unable to create watermark.', $e->getCode(), $e); + throw new LocalizedException( + __('Unable to create watermark.'), + $e, + $e->getCode() + ); } // merge layers @@ -346,12 +325,14 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity = * Checks required dependencies * * @return void - * @throws \Exception If some of dependencies are missing + * @throws \Magento\Framework\Exception\LocalizedException If some of dependencies are missing */ public function checkDependencies() { - if (!class_exists('\Imagick', false)) { - throw new \Exception("Required PHP extension 'Imagick' was not loaded."); + if (!class_exists('Imagick', false)) { + throw new LocalizedException( + __('Required PHP extension \'Imagick\' was not loaded.') + ); } } @@ -499,4 +480,86 @@ protected function _getImagickPixelObject($color = null) { return new \ImagickPixel($color); } + + /** + * Resizes watermark to desired size, when it is not stretched + * + * @param \Imagick $watermark + */ + private function resizeWatermark(\Imagick $watermark): void + { + if ($this->getWatermarkWidth() && + $this->getWatermarkHeight() && + $this->getWatermarkPosition() != self::POSITION_STRETCH + ) { + $watermark->resizeImage( + $this->getWatermarkWidth(), + $this->getWatermarkHeight(), + \Imagick::FILTER_CUBIC, + self::BLUR_FACTOR + ); + } + } + + /** + * Keeps transparenty if watermark is transparent + * + * @param \Imagick $watermark + */ + private function handleWatermarkAlphaChannel(\Imagick $watermark): void + { + if (method_exists($watermark, 'getImageAlphaChannel')) { + // available from imagick 6.4.0 + if ($watermark->getImageAlphaChannel() == 0) { + $watermark->setImageAlphaChannel(\Imagick::ALPHACHANNEL_OPAQUE); + } + } + } + + /** + * Add tiled watermark at starting given X,Y position + * + * @param int $positionX + * @param int $positionY + * @param \Imagick $watermark + * @param bool $compositeChannels + */ + private function addTiledWatermark($positionX, $positionY, \Imagick $watermark, $compositeChannels): void + { + $offsetX = $positionX; + $offsetY = $positionY; + while ($offsetY <= $this->_imageSrcHeight + $watermark->getImageHeight()) { + while ($offsetX <= $this->_imageSrcWidth + $watermark->getImageWidth()) { + $this->_imageHandler->compositeImage( + $watermark, + \Imagick::COMPOSITE_OVER, + $offsetX, + $offsetY, + $compositeChannels + ); + $offsetX += $watermark->getImageWidth(); + } + $offsetX = $positionX; + $offsetY += $watermark->getImageHeight(); + } + } + + /** + * Add watermark at given X,Y position + * + * @param int $positionX + * @param int $positionY + * @param \Imagick $watermark + * @param bool $compositeChannels + */ + private function addSingleWatermark($positionX, int $positionY, \Imagick $watermark, bool $compositeChannels): void + { + $this->_imageHandler->compositeImage( + $watermark, + \Imagick::COMPOSITE_OVER, + $positionX, + $positionY, + $compositeChannels + ); + } } diff --git a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php index 0a2dbefff8ee0..54fa7a57c7c7e 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php +++ b/lib/internal/Magento/Framework/Image/Adapter/UploadConfigInterface.php @@ -9,6 +9,7 @@ /** * Interface UploadConfigInterface + * * @deprecated moved to proper namespace and extended * @see \Magento\Backend\Model\Image\UploadResizeConfigInterface; */ diff --git a/lib/internal/Magento/Framework/Image/AdapterFactory.php b/lib/internal/Magento/Framework/Image/AdapterFactory.php index 8cb7b65ae73c9..4a380bab433db 100644 --- a/lib/internal/Magento/Framework/Image/AdapterFactory.php +++ b/lib/internal/Magento/Framework/Image/AdapterFactory.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Image; +/** + * Factory for Adapters that Image Library is using to process images + */ class AdapterFactory { /** diff --git a/lib/internal/Magento/Framework/Image/Factory.php b/lib/internal/Magento/Framework/Image/Factory.php index a0fb6bef4ae46..06cada6504058 100644 --- a/lib/internal/Magento/Framework/Image/Factory.php +++ b/lib/internal/Magento/Framework/Image/Factory.php @@ -8,6 +8,9 @@ use Magento\Framework\ObjectManagerInterface; +/** + * Factory for object to manipulate images + */ class Factory { /** diff --git a/lib/internal/Magento/Framework/Locale/Resolver.php b/lib/internal/Magento/Framework/Locale/Resolver.php index d058bfd41ab1a..55ef2a4e9a30c 100644 --- a/lib/internal/Magento/Framework/Locale/Resolver.php +++ b/lib/internal/Magento/Framework/Locale/Resolver.php @@ -15,7 +15,7 @@ class Resolver implements ResolverInterface { /** - * Default locale + * Resolver default locale */ const DEFAULT_LOCALE = 'en_US'; @@ -79,7 +79,7 @@ public function __construct( $this->scopeConfig = $scopeConfig; $this->defaultLocalePath = $defaultLocalePath; $this->scopeType = $scopeType; - $this->deploymentConfig = $deploymentConfig ?: ObjectManager::getInstance()->create(DeploymentConfig::class); + $this->deploymentConfig = $deploymentConfig ?: ObjectManager::getInstance()->get(DeploymentConfig::class); $this->setLocale($locale); } diff --git a/lib/internal/Magento/Framework/Module/ModuleList.php b/lib/internal/Magento/Framework/Module/ModuleList.php index 5a60a1c102b05..b3cf433bbaf45 100644 --- a/lib/internal/Magento/Framework/Module/ModuleList.php +++ b/lib/internal/Magento/Framework/Module/ModuleList.php @@ -140,11 +140,8 @@ public function isModuleInfoAvailable() */ private function loadConfigData() { - if (null === $this->configData) { - $this->config->resetData(); - if (null !== $this->config->get(ConfigOptionsListConstants::KEY_MODULES)) { - $this->configData = $this->config->get(ConfigOptionsListConstants::KEY_MODULES); - } + if (null === $this->configData && null !== $this->config->get(ConfigOptionsListConstants::KEY_MODULES)) { + $this->configData = $this->config->get(ConfigOptionsListConstants::KEY_MODULES); } } } diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php index 3142bbbc6771a..f8b02d177e097 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ModuleListTest.php @@ -5,9 +5,14 @@ */ namespace Magento\Framework\Module\Test\Unit; -use \Magento\Framework\Module\ModuleList; +use Magento\Framework\Module\ModuleList; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class ModuleListTest extends \PHPUnit\Framework\TestCase +/** + * Test for module list + */ +class ModuleListTest extends TestCase { /** * Fixture for all modules' meta-information @@ -24,12 +29,12 @@ class ModuleListTest extends \PHPUnit\Framework\TestCase private static $enabledFixture = ['foo' => 1, 'bar' => 0]; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $config; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var MockObject */ private $loader; @@ -47,7 +52,6 @@ protected function setUp() public function testGetAll() { - $this->config->expects($this->once())->method('resetData'); $this->setLoadAllExpectation(); $this->setLoadConfigExpectation(); $expected = ['foo' => self::$allFixture['foo']]; @@ -65,7 +69,6 @@ public function testGetAllNoData() public function testGetOne() { - $this->config->expects($this->once())->method('resetData'); $this->setLoadAllExpectation(); $this->setLoadConfigExpectation(); $this->assertSame(['key' => 'value'], $this->model->getOne('foo')); @@ -74,7 +77,6 @@ public function testGetOne() public function testGetNames() { - $this->config->expects($this->once())->method('resetData'); $this->setLoadAllExpectation(false); $this->setLoadConfigExpectation(); $this->assertSame(['foo'], $this->model->getNames()); @@ -83,7 +85,6 @@ public function testGetNames() public function testHas() { - $this->config->expects($this->once())->method('resetData'); $this->setLoadAllExpectation(false); $this->setLoadConfigExpectation(); $this->assertTrue($this->model->has('foo')); @@ -92,7 +93,6 @@ public function testHas() public function testIsModuleInfoAvailable() { - $this->config->expects($this->once())->method('resetData'); $this->setLoadConfigExpectation(true); $this->assertTrue($this->model->isModuleInfoAvailable()); } diff --git a/lib/internal/Magento/Framework/View/Element/BlockFactory.php b/lib/internal/Magento/Framework/View/Element/BlockFactory.php index 068cb49a66319..d691af8d98f53 100644 --- a/lib/internal/Magento/Framework/View/Element/BlockFactory.php +++ b/lib/internal/Magento/Framework/View/Element/BlockFactory.php @@ -8,7 +8,7 @@ use Magento\Framework\ObjectManagerInterface; /** - * Class BlockFactory + * Creates Blocks * * @api */ diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index fbb84712b2afd..8f980d82d4be0 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -15,12 +15,13 @@ use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderFactory; use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface; use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer; use Magento\Framework\View\Element\UiComponentFactory; use Magento\Framework\View\Element\UiComponentInterface; use Magento\Framework\View\LayoutInterface as PageLayoutInterface; /** - * Class Context + * Request context for UI components to utilize. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -101,6 +102,11 @@ class Context implements ContextInterface */ private $authorization; + /** + * @var Sanitizer + */ + private $sanitizer; + /** * @param PageLayoutInterface $pageLayout * @param RequestInterface $request @@ -113,6 +119,7 @@ class Context implements ContextInterface * @param DataProviderInterface|null $dataProvider * @param string $namespace * @param AuthorizationInterface|null $authorization + * @param Sanitizer|null $sanitizer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -126,7 +133,8 @@ public function __construct( UiComponentFactory $uiComponentFactory, DataProviderInterface $dataProvider = null, $namespace = null, - AuthorizationInterface $authorization = null + AuthorizationInterface $authorization = null, + ?Sanitizer $sanitizer = null ) { $this->namespace = $namespace; $this->request = $request; @@ -141,6 +149,7 @@ public function __construct( $this->authorization = $authorization ?: ObjectManager::getInstance()->get( AuthorizationInterface::class ); + $this->sanitizer = $sanitizer ?? ObjectManager::getInstance()->get(Sanitizer::class); $this->setAcceptType(); } @@ -241,16 +250,20 @@ public function getDataProvider() */ public function getDataSourceData(UiComponentInterface $component) { + //Getting dynamic data for the component $dataSource = $component->getDataSourceData(); $this->prepareDataSource($dataSource, $component); $dataProviderConfig = $this->getDataProvider()->getConfigData(); + //Dynamic UI component data should not contain templates. + $config = $this->sanitizer->sanitize(array_merge($dataSource, $dataProviderConfig)); + return [ $this->getDataProvider()->getName() => [ 'type' => 'dataSource', 'name' => $this->getDataProvider()->getName(), 'dataScope' => $this->getNamespace(), 'config' => array_replace_recursive( - array_merge($dataSource, $dataProviderConfig), + $config, [ 'params' => [ 'namespace' => $this->getNamespace() diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/Sanitizer.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/Sanitizer.php new file mode 100644 index 0000000000000..27a42fb337ce8 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/Sanitizer.php @@ -0,0 +1,102 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\View\Element\UiComponent\DataProvider; + +use Magento\Framework\Phrase; + +/** + * Sanitizes data received from UI data providers. + */ +class Sanitizer +{ + /** + * Extract rendering config from given UI data. + * + * @param array $data + * @return bool|array + */ + private function extractConfig(array $data) + { + /** @var array|bool $config */ + $config = []; + if (array_key_exists('__disableTmpl', $data)) { + //UI data provider has explicitly provided rendering config. + $config = $data['__disableTmpl']; + unset($data['__disableTmpl']); + } + + return $config; + } + + /** + * Sanitizes data from a UI data provider. + * + * @param array $data + * @return array + */ + public function sanitize(array $data): array + { + $config = $this->extractConfig($data); + $toProcess = []; + array_walk( + $data, + function ($datum, string $key) use (&$config, &$toProcess) : void { + if (is_array($datum)) { + //Each array must have it's own __disableTmpl property + $toProcess[$key] = $datum; + } elseif (( + !is_bool($config) && !array_key_exists($key, $config) + ) + && (is_string($datum) || $datum instanceof Phrase) + && preg_match('/\$\{.+\}/', (string)$datum) + ) { + //Templating is not disabled for all properties or for this property specifically + //Property is a string that contains template syntax so we are disabling it's rendering + $config[$key] = true; + } + } + ); + if ($toProcess) { + //Processing sub-arrays + $data = array_replace($data, array_map([$this, 'sanitize'], $toProcess)); + } + if ($config !== []) { + //Some properties require rendering configuration. + $data['__disableTmpl'] = $config; + } + + return $data; + } + + /** + * Sanitize a component's metadata. + * + * Will sanitize full component's metadata as well as metadata of it's child components. + * + * @param array $meta + * @return array + */ + public function sanitizeComponentMetadata(array $meta): array + { + if (array_key_exists('arguments', $meta) + && is_array($meta['arguments']) + && array_key_exists('data', $meta['arguments']) + && is_array($meta['arguments']['data']) + && array_key_exists('config', $meta['arguments']['data']) + && is_array($meta['arguments']['data']['config']) + ) { + $meta['arguments']['data']['config'] = $this->sanitize($meta['arguments']['data']['config']); + } + if (array_key_exists('children', $meta) && is_array($meta['children'])) { + $meta['children'] = array_map([$this, 'sanitizeComponentMetadata'], $meta['children']); + } + + return $meta; + } +} diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/SubjectInterface.php b/lib/internal/Magento/Framework/View/Element/UiComponent/SubjectInterface.php index dce42950e0ab6..821ebbb4d5050 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/SubjectInterface.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/SubjectInterface.php @@ -12,6 +12,7 @@ interface SubjectInterface { /** * Attach an observer by type + * * @param string $type * @param ObserverInterface $observer * @return void @@ -20,6 +21,7 @@ public function attach($type, ObserverInterface $observer); /** * Detach an observer by type + * * @param string $type * @param ObserverInterface $observer * @return void @@ -28,6 +30,7 @@ public function detach($type, ObserverInterface $observer); /** * Notify an observer(s) by type + * * @param string $type * @return void */ diff --git a/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php index b395e95f0baaf..16c06fe3abf3a 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponentFactory.php @@ -17,10 +17,11 @@ use Magento\Framework\View\Element\UiComponent\ContextFactory; use Magento\Framework\Phrase; use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer; use Magento\Framework\View\Element\UiComponent\Factory\ComponentFactoryInterface; /** - * Class UiComponentFactory + * Factory that creates UI component descriptor based on configuration provided. * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -69,6 +70,11 @@ class UiComponentFactory extends DataObject */ private $definitionData; + /** + * @var Sanitizer + */ + private $sanitizer; + /** * @param ObjectManagerInterface $objectManager * @param ManagerInterface $componentManager @@ -78,6 +84,7 @@ class UiComponentFactory extends DataObject * @param array $componentChildFactories * @param DataInterface $definitionData * @param DataInterfaceFactory $configFactory + * @param Sanitizer|null $sanitizer */ public function __construct( ObjectManagerInterface $objectManager, @@ -87,7 +94,8 @@ public function __construct( array $data = [], array $componentChildFactories = [], DataInterface $definitionData = null, - DataInterfaceFactory $configFactory = null + DataInterfaceFactory $configFactory = null, + ?Sanitizer $sanitizer = null ) { $this->objectManager = $objectManager; $this->componentManager = $componentManager; @@ -98,6 +106,7 @@ public function __construct( parent::__construct($data); $this->definitionData = $definitionData ?: $this->objectManager->get(DataInterface::class); + $this->sanitizer = $sanitizer ?? $this->objectManager->get(Sanitizer::class); } /** @@ -198,8 +207,12 @@ protected function argumentsResolver($identifier, array $componentData) */ public function create($identifier, $name = null, array $arguments = []) { + //$argument contain dynamic data generated by UI component classes which should not contain templates. + $arguments = $this->sanitizer->sanitize($arguments); if ($name === null) { - $componentData = $this->configFactory->create(['componentName' => $identifier])->get($identifier); + /** @var DataInterface $config */ + $config = $this->configFactory->create(['componentName' => $identifier]); + $componentData = $config->get($identifier); $bundleComponents = [$identifier => $componentData]; list($className, $componentArguments) = $this->argumentsResolver( @@ -312,10 +325,10 @@ protected function mergeMetadata($identifier, array $bundleComponents, $reverseM { $dataProvider = $this->getDataProvider($identifier, $bundleComponents); if ($dataProvider instanceof DataProviderInterface) { + //Dynamic meta from data providers should not contain templates. + $metadata = $dataProvider->getMeta(); $metadata = [ - $identifier => [ - 'children' => $dataProvider->getMeta(), - ], + $identifier => $this->sanitizer->sanitizeComponentMetadata(['children' => $metadata]) ]; $bundleComponents = $this->mergeMetadataItem($bundleComponents, $metadata, $reverseMerge); } diff --git a/lib/internal/Magento/Framework/View/Layout.php b/lib/internal/Magento/Framework/View/Layout.php index a622006f32a1e..ebefc6200cdfa 100644 --- a/lib/internal/Magento/Framework/View/Layout.php +++ b/lib/internal/Magento/Framework/View/Layout.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\View; use Magento\Framework\App\ObjectManager; @@ -261,7 +263,7 @@ protected function build() /** * Public build. * - * Will be eliminated in MAGETWO-28359 + * @todo Will be eliminated in MAGETWO-28359 * * @return void */ @@ -1101,15 +1103,24 @@ protected function _prepareMessageGroup($messageGroups) } /** - * Check is exists non-cacheable layout elements + * Check existed non-cacheable layout elements. * * @return bool */ public function isCacheable() { $this->build(); - $cacheableXml = !(bool)count($this->getXml()->xpath('//' . Element::TYPE_BLOCK . '[@cacheable="false"]')); - return $this->cacheable && $cacheableXml; + $elements = $this->getXml()->xpath('//' . Element::TYPE_BLOCK . '[@cacheable="false"]'); + $cacheable = $this->cacheable; + foreach ($elements as $element) { + $blockName = $element->getBlockName(); + if ($blockName !== false && $this->structure->hasElement($blockName)) { + $cacheable = false; + break; + } + } + + return $cacheable; } /** diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/UiComponent/DataProvider/SanitizerTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/UiComponent/DataProvider/SanitizerTest.php new file mode 100644 index 0000000000000..75fbfd868cfc1 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/UiComponent/DataProvider/SanitizerTest.php @@ -0,0 +1,185 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\View\Test\Unit\Element\UiComponent\DataProvider; + +use Magento\Framework\View\Element\UiComponent\DataProvider\Sanitizer; +use PHPUnit\Framework\TestCase; + +/** + * Test sanitizer for different kind of scenarios. + */ +class SanitizerTest extends TestCase +{ + /** + * @var Sanitizer + */ + private $sanitizer; + + /** + * @inheritDoc + */ + protected function setUp() + { + $this->sanitizer = new Sanitizer(); + } + + /** + * Data sets to sanitize. + * + * @return array + */ + public function getSanitizeDataSets(): array + { + return [ + 'simpleSet' => [ + ['foo' => '${\'bar\'}', 'xyz' => 42], + ['foo' => '${\'bar\'}', 'xyz' => 42, '__disableTmpl' => ['foo' => true]] + ], + 'configuredSet' => [ + ['foo' => 'bar', 'xyz' => '${\'zyx\'}', '__disableTmpl' => true], + ['foo' => 'bar', 'xyz' => '${\'zyx\'}', '__disableTmpl' => true] + ], + 'partiallyConfiguredSet' => [ + ['foo' => '${\'bar\'}', 'xyz' => '${\'zyx\'}', '__disableTmpl' => ['foo' => false]], + ['foo' => '${\'bar\'}', 'xyz' => '${\'zyx\'}', '__disableTmpl' => ['foo' => false, 'xyz' => true]] + ], + 'enabledSet' => [ + ['foo' => 'bar', 'xyz' => '${\'zyx\'}', '__disableTmpl' => false], + ['foo' => 'bar', 'xyz' => '${\'zyx\'}', '__disableTmpl' => false] + ], + 'complexSet' => [ + [ + 'foo' => 'bar', + 'sub1' => ['foo' => '${\'bar\'}'], + 'sub2' => [ + 'field' => '${\'value\'}', + 'subSub1' => ['foo' => 'bar'], + 'subSub2' => ['foo' => '${\'bar\'}', '__disableTmpl' => false], + 'subSub3' => [ + 'fooSub' => [ + 'foo' => '${\'bar\'}', + '__disableTmpl' => false, + 'subSubSub1' => ['field' => '${\'value\'}'] + ] + ], + 'subSub4' => [['foo' => '${\'bar\'}'], ['foo' => '${\'bar\'}', 'xyz' => '${\'zyx\'}']] + ] + ], + [ + 'foo' => 'bar', + 'sub1' => ['foo' => '${\'bar\'}', '__disableTmpl' => ['foo' => true]], + 'sub2' => [ + 'field' => '${\'value\'}', + 'subSub1' => ['foo' => 'bar'], + 'subSub2' => ['foo' => '${\'bar\'}', '__disableTmpl' => false], + 'subSub3' => [ + 'fooSub' => [ + 'foo' => '${\'bar\'}', + '__disableTmpl' => false, + 'subSubSub1' => ['field' => '${\'value\'}', '__disableTmpl' => ['field' => true]] + ] + ], + 'subSub4' => [ + ['foo' => '${\'bar\'}', '__disableTmpl' => ['foo' => true]], + [ + 'foo' => '${\'bar\'}', + 'xyz' => '${\'zyx\'}', + '__disableTmpl' => ['foo' => true, 'xyz' => true] + ] + ], + '__disableTmpl' => ['field' => true] + ] + ] + ] + ]; + } + + /** + * Test sanitize method for different data sets. + * + * @param array $input + * @param array $expectedOutput + * @return void + * @dataProvider getSanitizeDataSets + */ + public function testSanitize(array $input, array $expectedOutput): void + { + $this->assertEquals($expectedOutput, $this->sanitizer->sanitize($input)); + } + + /** + * Full UI component data sets to sanitize. + * + * @return array + */ + public function getSanitizeComponentDataSets(): array + { + return [ + 'simpleComponent' => [ + [ + 'arguments' => ['data' => ['config' => ['foo' => '${\'bar\'}', 'xyz' => 42]]], + 'children' => [ + 'child_component' => [ + 'arguments' => ['data' => ['config' => ['foo' => '${\'bar\'}', 'xyz' => '${\'xyz\'}']]] + ] + ] + ], + [ + 'arguments' => [ + 'data' => [ + 'config' => ['foo' => '${\'bar\'}', 'xyz' => 42, '__disableTmpl' => ['foo' => true]] + ] + ], + 'children' => [ + 'child_component' => [ + 'arguments' => [ + 'data' => [ + 'config' => [ + 'foo' => '${\'bar\'}', + 'xyz' => '${\'xyz\'}', + '__disableTmpl' => ['foo' => true, 'xyz' => true] + ] + ] + ] + ] + ] + ] + ], + 'argumentsOnly' => [ + ['arguments' => ['data' => ['config' => ['foo' => '${\'bar\'}']]]], + ['arguments' => ['data' => ['config' => ['foo' => '${\'bar\'}', '__disableTmpl' => ['foo' => true]]]]] + ], + 'childrenOnly' => [ + ['children' => ['child1' => ['arguments' => ['data' => ['config' => ['foo' => '${\'bar\'}']]]]]], + [ + 'children' => [ + 'child1' => [ + 'arguments' => [ + 'data' => ['config' => ['foo' => '${\'bar\'}', '__disableTmpl' => ['foo' => true]]] + ] + ] + ] + ] + ] + ]; + } + + /** + * Test sanitizeComponentMetadata method for different data sets. + * + * @param array $input + * @param array $expectedOutput + * @return void + * @dataProvider getSanitizeComponentDataSets + */ + public function testSanitizeComponentMetadata(array $input, array $expectedOutput): void + { + $this->assertEquals($expectedOutput, $this->sanitizer->sanitizeComponentMetadata($input)); + } +} diff --git a/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php b/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php index a11d132b193a0..b9754150bb92e 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/LayoutTest.php @@ -3,172 +3,193 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework\View\Test\Unit; +use Magento\Framework\App\State; +use Magento\Framework\Cache\FrontendInterface; +use Magento\Framework\DataObject; +use Magento\Framework\Event\ManagerInterface as EventManager; +use Magento\Framework\Message\ManagerInterface; use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\View\Design\Theme\ResolverInterface; +use Magento\Framework\View\Design\ThemeInterface; +use Magento\Framework\View\Element\AbstractBlock; +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Layout; +use Magento\Framework\View\Layout\Data\Structure as LayoutStructure; +use Magento\Framework\View\Layout\Element; +use Magento\Framework\View\Layout\Generator\Block; +use Magento\Framework\View\Layout\Generator\Container; +use Magento\Framework\View\Layout\Generator\Context; +use Magento\Framework\View\Layout\Generator\ContextFactory; +use Magento\Framework\View\Layout\GeneratorPool; +use Magento\Framework\View\Layout\ProcessorFactory; +use Magento\Framework\View\Layout\Reader\Context as LayoutReaderContext; +use Magento\Framework\View\Layout\Reader\ContextFactory as LayoutReaderContextFactory; +use Magento\Framework\View\Layout\ReaderPool; +use Magento\Framework\View\Layout\ScheduledStructure; +use Magento\Framework\View\Model\Layout\Merge; +use Magento\Framework\View\Page\Config\Structure; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; /** + * Unit tests for \Magento\Framework\View\Layout class. + * * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class LayoutTest extends \PHPUnit\Framework\TestCase +class LayoutTest extends TestCase { /** - * @var \Magento\Framework\View\Layout + * @var Layout */ - protected $model; + private $model; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var LayoutStructure|MockObject */ - protected $structureMock; + private $structureMock; /** - * @var \Magento\Framework\View\Layout\ProcessorFactory|\PHPUnit_Framework_MockObject_MockObject + * @var ProcessorFactory|MockObject */ - protected $processorFactoryMock; + private $processorFactoryMock; /** - * @var \Magento\Framework\View\Design\Theme\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ResolverInterface|MockObject */ - protected $themeResolverMock; + private $themeResolverMock; /** - * @var \Magento\Framework\View\Model\Layout\Merge|\PHPUnit_Framework_MockObject_MockObject + * @var Merge|MockObject */ - protected $processorMock; + private $processorMock; /** - * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var EventManager|MockObject */ - protected $eventManagerMock; + private $eventManagerMock; /** - * @var \Magento\Framework\View\Layout\Generator\Block|\PHPUnit_Framework_MockObject_MockObject + * @var Block|MockObject */ - protected $generatorBlockMock; + private $generatorBlockMock; /** - * @var \Magento\Framework\View\Layout\Generator\Container|\PHPUnit_Framework_MockObject_MockObject + * @var Container|MockObject */ - protected $generatorContainerMock; + private $generatorContainerMock; /** - * @var \Magento\Framework\Cache\FrontendInterface|\PHPUnit_Framework_MockObject_MockObject + * @var FrontendInterface|MockObject */ - protected $cacheMock; + private $cacheMock; /** - * @var \Magento\Framework\View\Layout\ReaderPool|\PHPUnit_Framework_MockObject_MockObject + * @var ReaderPool|MockObject */ - protected $readerPoolMock; + private $readerPoolMock; /** - * @var \Magento\Framework\View\Layout\GeneratorPool|\PHPUnit_Framework_MockObject_MockObject + * @var GeneratorPool|MockObject */ - protected $generatorPoolMock; + private $generatorPoolMock; /** - * @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ManagerInterface|MockObject */ - protected $messageManagerMock; + private $messageManagerMock; /** - * @var \Magento\Framework\View\Layout\Reader\ContextFactory|\PHPUnit_Framework_MockObject_MockObject + * @var LayoutReaderContextFactory|MockObject */ - protected $readerContextFactoryMock; + private $readerContextFactoryMock; /** - * @var \Magento\Framework\View\Layout\Reader\Context|\PHPUnit_Framework_MockObject_MockObject + * @var Layout\Reader\Context|MockObject */ - protected $readerContextMock; + private $readerContextMock; /** - * @var \Magento\Framework\View\Page\Config\Structure|\PHPUnit_Framework_MockObject_MockObject + * @var Structure|MockObject */ private $pageConfigStructure; /** - * @var \Magento\Framework\View\Layout\ScheduledStructure|\PHPUnit_Framework_MockObject_MockObject + * @var ScheduledStructure|MockObject */ private $layoutScheduledSructure; /** - * @var \Magento\Framework\View\Layout\Generator\ContextFactory|\PHPUnit_Framework_MockObject_MockObject + * @var ContextFactory|MockObject */ - protected $generatorContextFactoryMock; + private $generatorContextFactoryMock; /** - * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject + * @var State|MockObject */ - protected $appStateMock; + private $appStateMock; /** - * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var LoggerInterface|MockObject */ - protected $loggerMock; + private $loggerMock; /** - * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var SerializerInterface|MockObject */ private $serializer; /** + * @inheritdoc * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function setUp() { - $this->structureMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Data\Structure::class) + $this->structureMock = $this->getMockBuilder(LayoutStructure::class) ->disableOriginalConstructor() ->getMock(); - $this->processorFactoryMock = $this->createPartialMock( - \Magento\Framework\View\Layout\ProcessorFactory::class, - ['create'] - ); - $this->themeResolverMock = $this->getMockForAbstractClass( - \Magento\Framework\View\Design\Theme\ResolverInterface::class - ); - $this->processorMock = $this->createMock(\Magento\Framework\View\Model\Layout\Merge::class); - $this->eventManagerMock = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); - $this->generatorBlockMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Generator\Block::class) - ->disableOriginalConstructor()->getMock(); - $this->generatorContainerMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Generator\Container::class) - ->disableOriginalConstructor()->getMock(); - $this->cacheMock = $this->getMockBuilder(\Magento\Framework\Cache\FrontendInterface::class) + $this->processorFactoryMock = $this->createPartialMock(ProcessorFactory::class, ['create']); + $this->themeResolverMock = $this->getMockForAbstractClass(ResolverInterface::class); + $this->processorMock = $this->createMock(Merge::class); + $this->eventManagerMock = $this->getMockForAbstractClass(EventManager::class); + $this->generatorBlockMock = $this->getMockBuilder(Block::class) ->disableOriginalConstructor() ->getMock(); - $this->readerPoolMock = $this->getMockBuilder(\Magento\Framework\View\Layout\ReaderPool::class) + $this->generatorContainerMock = $this->getMockBuilder(Container::class) ->disableOriginalConstructor() ->getMock(); - $this->messageManagerMock = $this->getMockBuilder(\Magento\Framework\Message\ManagerInterface::class) + $this->cacheMock = $this->getMockForAbstractClass(FrontendInterface::class); + $this->readerPoolMock = $this->getMockBuilder(ReaderPool::class) + ->disableOriginalConstructor() + ->getMock(); + $this->messageManagerMock = $this->getMockForAbstractClass(ManagerInterface::class); + $this->generatorPoolMock = $this->getMockBuilder(GeneratorPool::class) ->disableOriginalConstructor() ->getMock(); - - $this->generatorPoolMock = $this->getMockBuilder(\Magento\Framework\View\Layout\GeneratorPool::class) - ->disableOriginalConstructor()->getMock(); $this->generatorPoolMock->expects($this->any()) ->method('getGenerator') - ->will( - $this->returnValueMap( - [ - [\Magento\Framework\View\Layout\Generator\Block::TYPE, $this->generatorBlockMock], - [\Magento\Framework\View\Layout\Generator\Container::TYPE, $this->generatorContainerMock], - ] - ) + ->willReturnMap( + [ + [Block::TYPE, $this->generatorBlockMock], + [Container::TYPE, $this->generatorContainerMock], + ] ); - - $this->readerContextFactoryMock = $this->getMockBuilder( - \Magento\Framework\View\Layout\Reader\ContextFactory::class - )->disableOriginalConstructor()->getMock(); - - $this->pageConfigStructure = $this->getMockBuilder(\Magento\Framework\View\Page\Config\Structure::class) + $this->readerContextFactoryMock = $this->getMockBuilder(LayoutReaderContextFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->pageConfigStructure = $this->getMockBuilder(Structure::class) ->setMethods(['__toArray', 'populateWithArray']) ->getMock(); - $this->layoutScheduledSructure = $this->getMockBuilder(\Magento\Framework\View\Layout\ScheduledStructure::class) + $this->layoutScheduledSructure = $this->getMockBuilder(ScheduledStructure::class) ->setMethods(['__toArray', 'populateWithArray']) ->getMock(); - $this->readerContextMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Reader\Context::class) + $this->readerContextMock = $this->getMockBuilder(LayoutReaderContext::class) ->setMethods(['getPageConfigStructure', 'getScheduledStructure']) ->disableOriginalConstructor() ->getMock(); @@ -176,125 +197,135 @@ protected function setUp() ->willReturn($this->pageConfigStructure); $this->readerContextMock->expects($this->any())->method('getScheduledStructure') ->willReturn($this->layoutScheduledSructure); - - $this->generatorContextFactoryMock = $this->getMockBuilder( - \Magento\Framework\View\Layout\Generator\ContextFactory::class - ) + $this->generatorContextFactoryMock = $this->getMockBuilder(ContextFactory::class) ->disableOriginalConstructor() ->getMock(); - $this->appStateMock = $this->getMockBuilder(\Magento\Framework\App\State::class) + $this->appStateMock = $this->getMockBuilder(State::class) ->disableOriginalConstructor() ->getMock(); - $this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) - ->getMock(); - $this->serializer = $this->createMock(\Magento\Framework\Serialize\SerializerInterface::class); + $this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class); + $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class); $this->serializer->expects($this->any())->method('serialize') ->willReturnCallback( function ($value) { return json_encode($value); } ); - $this->serializer->expects( - $this->any() - )->method('unserialize') + $this->serializer->expects($this->any())->method('unserialize') ->willReturnCallback( function ($value) { return json_decode($value, true); } ); - $this->model = new \Magento\Framework\View\Layout( - $this->processorFactoryMock, - $this->eventManagerMock, - $this->structureMock, - $this->messageManagerMock, - $this->themeResolverMock, - $this->readerPoolMock, - $this->generatorPoolMock, - $this->cacheMock, - $this->readerContextFactoryMock, - $this->generatorContextFactoryMock, - $this->appStateMock, - $this->loggerMock, - true, - $this->serializer + $this->model = (new ObjectManagerHelper($this))->getObject( + Layout::class, + [ + 'processorFactory' => $this->processorFactoryMock, + 'eventManager' => $this->eventManagerMock, + 'structure' => $this->structureMock, + 'messageManager' => $this->messageManagerMock, + 'themeResolver' => $this->themeResolverMock, + 'readerPool' => $this->readerPoolMock, + 'generatorPool' => $this->generatorPoolMock, + 'cache' => $this->cacheMock, + 'readerContextFactory' => $this->readerContextFactoryMock, + 'generatorContextFactory' => $this->generatorContextFactoryMock, + 'appState' => $this->appStateMock, + 'logger' => $this->loggerMock, + 'cacheable' => true, + 'serializer' => $this->serializer, + ] ); } - public function testCreateBlockSuccess() + /** + * @return void + */ + public function testCreateBlockSuccess(): void { - $blockMock = $this->getMockBuilder(\Magento\Framework\View\Element\AbstractBlock::class) + $blockMock = $this->getMockBuilder(AbstractBlock::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->structureMock->expects($this->once()) ->method('createStructuralElement') ->with( 'blockname', - \Magento\Framework\View\Layout\Element::TYPE_BLOCK, - \Magento\Framework\View\Element\AbstractBlock::class - )->willReturn('blockname'); - $this->generatorBlockMock->expects($this->once())->method('createBlock')->will($this->returnValue($blockMock)); + Element::TYPE_BLOCK, + AbstractBlock::class + ) + ->willReturn('blockname'); + $this->generatorBlockMock->expects($this->once())->method('createBlock')->willReturn($blockMock); - $this->model->createBlock(\Magento\Framework\View\Element\AbstractBlock::class, 'blockname', []); + $this->model->createBlock(AbstractBlock::class, 'blockname', []); $this->assertInstanceOf( - \Magento\Framework\View\Element\AbstractBlock::class, + AbstractBlock::class, $this->model->getBlock('blockname') ); $this->assertFalse($this->model->getBlock('not_exist')); } - public function testGetUpdate() + /** + * @return void + */ + public function testGetUpdate(): void { - $themeMock = $this->getMockForAbstractClass(\Magento\Framework\View\Design\ThemeInterface::class); + $themeMock = $this->getMockForAbstractClass(ThemeInterface::class); $this->themeResolverMock->expects($this->once()) ->method('get') - ->will($this->returnValue($themeMock)); + ->willReturn($themeMock); $this->processorFactoryMock->expects($this->once()) ->method('create') ->with(['theme' => $themeMock]) - ->will($this->returnValue($this->processorMock)); + ->willReturn($this->processorMock); $this->assertEquals($this->processorMock, $this->model->getUpdate()); $this->assertEquals($this->processorMock, $this->model->getUpdate()); } - public function testGenerateXml() + /** + * @return void + */ + public function testGenerateXml(): void { - $themeMock = $this->getMockForAbstractClass(\Magento\Framework\View\Design\ThemeInterface::class); + $themeMock = $this->getMockForAbstractClass(ThemeInterface::class); $this->themeResolverMock->expects($this->once()) ->method('get') - ->will($this->returnValue($themeMock)); + ->willReturn($themeMock); $this->processorFactoryMock->expects($this->once()) ->method('create') ->with(['theme' => $themeMock]) - ->will($this->returnValue($this->processorMock)); + ->willReturn($this->processorMock); $xmlString = '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . '<some_update>123</some_update></layout>'; - $xml = simplexml_load_string($xmlString, \Magento\Framework\View\Layout\Element::class); + $xml = simplexml_load_string($xmlString, Element::class); $this->processorMock->expects($this->once()) ->method('asSimplexml') - ->will($this->returnValue($xml)); + ->willReturn($xml); $this->structureMock->expects($this->once()) ->method('importElements') ->with($this->equalTo([])) - ->will($this->returnSelf()); + ->willReturnSelf(); $this->assertSame($this->model, $this->model->generateXml()); $this->assertSame('<some_update>123</some_update>', $this->model->getNode('some_update')->asXML()); } - public function testGetChildBlock() + /** + * @return void + */ + public function testGetChildBlock(): void { $customBlockName = 'custom_block'; $customBlockParentName = 'custom_block_parent'; $customBlockAlias = 'custom_block_alias'; - $blockMock = $this->getMockBuilder(\Magento\Framework\View\Element\Template::class) + $blockMock = $this->getMockBuilder(Template::class) ->disableOriginalConstructor() ->getMock(); @@ -311,16 +342,19 @@ public function testGetChildBlock() $this->structureMock->expects($this->once()) ->method('getAttribute') ->with($customBlockName, 'type') - ->willReturn(\Magento\Framework\View\Layout\Element::TYPE_BLOCK); + ->willReturn(Element::TYPE_BLOCK); $this->model->setBlock($customBlockName, $blockMock); $this->assertInstanceOf( - \Magento\Framework\View\Element\AbstractBlock::class, + AbstractBlock::class, $this->model->getChildBlock($customBlockParentName, $customBlockAlias) ); } - public function testGetChildNonExistBlock() + /** + * @return void + */ + public function testGetChildNonExistBlock(): void { $this->structureMock->expects($this->once()) ->method('getChildId') @@ -329,7 +363,10 @@ public function testGetChildNonExistBlock() $this->assertFalse($this->model->getChildBlock('non_exist_parent', 'non_exist_alias')); } - public function testSetChild() + /** + * @return void + */ + public function testSetChild(): void { $elementName = 'child'; $parentName = 'parent'; @@ -337,104 +374,131 @@ public function testSetChild() $this->structureMock->expects($this->once()) ->method('setAsChild') ->with($this->equalTo($elementName), $this->equalTo($parentName), $this->equalTo($alias)) - ->will($this->returnSelf()); + ->willReturnSelf(); $this->assertSame($this->model, $this->model->setChild($parentName, $elementName, $alias)); } - public function testUnsetChild() + /** + * @return void + */ + public function testUnsetChild(): void { $parentName = 'parent'; $alias = 'some_alias'; $this->structureMock->expects($this->once()) ->method('unsetChild') ->with($this->equalTo($parentName), $this->equalTo($alias)) - ->will($this->returnSelf()); + ->willReturnSelf(); $this->assertSame($this->model, $this->model->unsetChild($parentName, $alias)); } - public function testGetChildNames() + /** + * @return void + */ + public function testGetChildNames(): void { $parentName = 'parent'; $childrenArray = ['key1' => 'value1', 'key2' => 'value2']; $this->structureMock->expects($this->once()) ->method('getChildren') ->with($this->equalTo($parentName)) - ->will($this->returnValue($childrenArray)); + ->willReturn($childrenArray); $this->assertSame(['key1', 'key2'], $this->model->getChildNames($parentName)); } - public function testGetChildBlocks() + /** + * @return void + */ + public function testGetChildBlocks(): void { $parentName = 'parent'; $childrenArray = ['block_name' => 'value1']; $this->structureMock->expects($this->once()) ->method('getChildren') ->with($this->equalTo($parentName)) - ->will($this->returnValue($childrenArray)); + ->willReturn($childrenArray); - $blockMock = $this->getMockBuilder(\Magento\Framework\View\Element\AbstractBlock::class) + $blockMock = $this->getMockBuilder(AbstractBlock::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->structureMock->expects($this->once()) ->method('createStructuralElement') ->with( 'block_name', - \Magento\Framework\View\Layout\Element::TYPE_BLOCK, - \Magento\Framework\View\Element\AbstractBlock::class - )->willReturn('block_name'); - $this->generatorBlockMock->expects($this->once())->method('createBlock')->will($this->returnValue($blockMock)); + Element::TYPE_BLOCK, + AbstractBlock::class + ) + ->willReturn('block_name'); + $this->generatorBlockMock->expects($this->once()) + ->method('createBlock') + ->willReturn($blockMock); $this->assertSame( $blockMock, - $this->model->createBlock(\Magento\Framework\View\Element\AbstractBlock::class, 'block_name', []) + $this->model->createBlock(AbstractBlock::class, 'block_name', []) ); $this->assertSame(['value1' => $blockMock], $this->model->getChildBlocks($parentName)); } - public function testGetChildName() + /** + * @return void + */ + public function testGetChildName(): void { $parentName = 'parent'; $alias = 'some_alias'; $this->structureMock->expects($this->once()) ->method('getChildId') ->with($this->equalTo($parentName), $this->equalTo($alias)) - ->will($this->returnValue('1')); + ->willReturn('1'); $this->assertSame('1', $this->model->getChildName($parentName, $alias)); } - public function testAddToParentGroup() + /** + * @return void + */ + public function testAddToParentGroup(): void { $blockName = 'block_name'; $parentGroup = 'parent_group'; $this->structureMock->expects($this->once()) ->method('addToParentGroup') ->with($this->equalTo($blockName), $this->equalTo($parentGroup)) - ->will($this->returnSelf()); + ->willReturnSelf(); $this->assertSame($this->structureMock, $this->model->addToParentGroup($blockName, $parentGroup)); } - public function testGetGroupChildNames() + /** + * @return void + */ + public function testGetGroupChildNames(): void { $blockName = 'block_name'; $groupName = 'group_name'; $this->structureMock->expects($this->once()) ->method('getGroupChildNames') ->with($this->equalTo($blockName), $this->equalTo($groupName)) - ->will($this->returnSelf()); + ->willReturnSelf(); $this->assertSame($this->structureMock, $this->model->getGroupChildNames($blockName, $groupName)); } - public function testHasElement() + /** + * @return void + */ + public function testHasElement(): void { $elementName = 'name'; $this->structureMock->expects($this->once()) ->method('hasElement') ->with($this->equalTo($elementName)) - ->will($this->returnValue(true)); + ->willReturn(true); $this->assertTrue($this->model->hasElement($elementName)); } - public function testGetElementProperty() + /** + * @return void + */ + public function testGetElementProperty(): void { $elementName = 'name'; $elementAttr = 'attribute'; @@ -442,7 +506,7 @@ public function testGetElementProperty() $this->structureMock->expects($this->once()) ->method('getAttribute') ->with($this->equalTo($elementName), $this->equalTo($elementAttr)) - ->will($this->returnValue($result)); + ->willReturn($result); $this->assertSame($result, $this->model->getElementProperty($elementName, $elementAttr)); } @@ -450,20 +514,21 @@ public function testGetElementProperty() * @param bool $hasElement * @param string $attribute * @param bool $result + * @return void * @dataProvider isContainerDataProvider */ - public function testIsContainer($hasElement, $attribute, $result) + public function testIsContainer($hasElement, $attribute, $result): void { $elementName = 'element_name'; $this->structureMock->expects($this->once()) ->method('hasElement') ->with($this->equalTo($elementName)) - ->will($this->returnValue($hasElement)); + ->willReturn($hasElement); if ($hasElement) { $this->structureMock->expects($this->once()) ->method('getAttribute') ->with($this->equalTo($elementName), $this->equalTo('type')) - ->will($this->returnValue($attribute)); + ->willReturn($attribute); } $this->assertSame($result, $this->model->isContainer($elementName)); } @@ -471,7 +536,7 @@ public function testIsContainer($hasElement, $attribute, $result) /** * @return array */ - public function isContainerDataProvider() + public function isContainerDataProvider(): array { return [ [false, '', false], @@ -485,25 +550,26 @@ public function isContainerDataProvider() * @param bool $parentName * @param array $containerConfig * @param bool $result + * @return void * @dataProvider isManipulationAllowedDataProvider */ - public function testIsManipulationAllowed($parentName, $containerConfig, $result) + public function testIsManipulationAllowed($parentName, $containerConfig, $result): void { $elementName = 'element_name'; $this->structureMock->expects($this->once()) ->method('getParentId') ->with($this->equalTo($elementName)) - ->will($this->returnValue($parentName)); + ->willReturn($parentName); if ($parentName) { $this->structureMock->expects($this->once()) ->method('hasElement') ->with($this->equalTo($parentName)) - ->will($this->returnValue($containerConfig['has_element'])); + ->willReturn($containerConfig['has_element']); if ($containerConfig['has_element']) { $this->structureMock->expects($this->once()) ->method('getAttribute') ->with($this->equalTo($parentName), $this->equalTo('type')) - ->will($this->returnValue($containerConfig['attribute'])); + ->willReturn($containerConfig['attribute']); } } @@ -513,7 +579,7 @@ public function testIsManipulationAllowed($parentName, $containerConfig, $result /** * @return array */ - public function isManipulationAllowedDataProvider() + public function isManipulationAllowedDataProvider(): array { return [ ['parent', ['has_element' => true, 'attribute' => 'container'], true], @@ -526,11 +592,12 @@ public function isManipulationAllowedDataProvider() * @covers \Magento\Framework\View\Layout::setBlock * @covers \Magento\Framework\View\Layout::getAllBlocks * @covers \Magento\Framework\View\Layout::unsetElement + * @return void */ - public function testSetGetBlock() + public function testSetGetBlock(): void { $blockName = 'some_name'; - $blockMock = $this->getMockBuilder(\Magento\Framework\View\Element\AbstractBlock::class) + $blockMock = $this->getMockBuilder(AbstractBlock::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->assertSame($this->model, $this->model->setBlock($blockName, $blockMock)); @@ -538,40 +605,49 @@ public function testSetGetBlock() $this->structureMock->expects($this->once()) ->method('unsetElement') ->with($this->equalTo($blockName)) - ->will($this->returnSelf()); + ->willReturnSelf(); $this->assertSame($this->model, $this->model->unsetElement($blockName)); $this->assertSame([], $this->model->getAllBlocks()); } - public function testRenameElement() + /** + * @return void + */ + public function testRenameElement(): void { $oldName = 'old_name'; $newName = 'new_name'; - $blockMock = $this->getMockBuilder(\Magento\Framework\View\Element\AbstractBlock::class) + $blockMock = $this->getMockBuilder(AbstractBlock::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->structureMock->expects($this->once()) ->method('renameElement') ->with($this->equalTo($oldName), $this->equalTo($newName)) - ->will($this->returnSelf()); + ->willReturnSelf(); $this->assertSame($this->model, $this->model->setBlock($oldName, $blockMock)); $this->assertSame($this->model, $this->model->renameElement($oldName, $newName)); $this->assertSame([$newName => $blockMock], $this->model->getAllBlocks()); } - public function testGetParentName() + /** + * @return void + */ + public function testGetParentName(): void { $childName = 'child_name'; $parentId = 'parent_id'; $this->structureMock->expects($this->once()) ->method('getParentId') ->with($this->equalTo($childName)) - ->will($this->returnValue($parentId)); + ->willReturn($parentId); $this->assertSame($parentId, $this->model->getParentName($childName)); } - public function testGetElementAlias() + /** + * @return void + */ + public function testGetElementAlias(): void { $name = 'child_name'; $parentId = 'parent_id'; @@ -579,21 +655,27 @@ public function testGetElementAlias() $this->structureMock->expects($this->once()) ->method('getParentId') ->with($this->equalTo($name)) - ->will($this->returnValue($parentId)); + ->willReturn($parentId); $this->structureMock->expects($this->once()) ->method('getChildAlias') ->with($this->equalTo($parentId), $this->equalTo($name)) - ->will($this->returnValue($alias)); + ->willReturn($alias); $this->assertSame($alias, $this->model->getElementAlias($name)); } - public function testAddRemoveOutputElement() + /** + * @return void + */ + public function testAddRemoveOutputElement(): void { $this->assertSame($this->model, $this->model->addOutputElement('name')); $this->assertSame($this->model, $this->model->removeOutputElement('name')); } - public function testIsPrivate() + /** + * @return void + */ + public function testIsPrivate(): void { $this->assertFalse($this->model->isPrivate()); $this->assertSame($this->model, $this->model->setIsPrivate(true)); @@ -603,18 +685,19 @@ public function testIsPrivate() /** * @param array $type * @param array $blockInstance + * @return void * @dataProvider getBlockSingletonDataProvider */ - public function testGetBlockSingleton($type, $blockInstance, $isAbstract) + public function testGetBlockSingleton($type, $blockInstance, $isAbstract): void { $blockMock = $this->createMock($blockInstance); - $this->generatorBlockMock->expects($this->once())->method('createBlock')->will($this->returnValue($blockMock)); + $this->generatorBlockMock->expects($this->once())->method('createBlock')->willReturn($blockMock); if ($isAbstract) { $blockMock->expects($this->any()) ->method('setLayout') ->with($this->equalTo($this->model)) - ->will($this->returnSelf()); + ->willReturnSelf(); } $this->assertInstanceOf($blockInstance, $this->model->getBlockSingleton($type)); // singleton test @@ -624,11 +707,12 @@ public function testGetBlockSingleton($type, $blockInstance, $isAbstract) /** * @return array */ - public function getBlockSingletonDataProvider() + public function getBlockSingletonDataProvider(): array { return [ [ - 'some_type', \Magento\Framework\View\Element\Template::class, + 'some_type', + Template::class, true, ], ]; @@ -638,9 +722,10 @@ public function getBlockSingletonDataProvider() * @param array $rendererData * @param array $getData * @param bool $result + * @return void * @dataProvider getRendererOptionsDataProvider */ - public function testAddGetRendererOptions($rendererData, $getData, $result) + public function testAddGetRendererOptions($rendererData, $getData, $result): void { $this->assertSame( $this->model, @@ -662,7 +747,7 @@ public function testAddGetRendererOptions($rendererData, $getData, $result) /** * @return array */ - public function getRendererOptionsDataProvider() + public function getRendererOptionsDataProvider(): array { $rendererData = [ 'namespace' => 'namespace_value', @@ -718,47 +803,94 @@ public function getRendererOptionsDataProvider() /** * @param string $xmlString - * @param bool $result + * @param string $blockName + * @param bool $hasElement + * @param bool $cacheable + * @return void * @dataProvider isCacheableDataProvider */ - public function testIsCacheable($xmlString, $result) + public function testIsCacheable(string $xmlString, string $blockName, bool $hasElement, bool $cacheable): void { - $xml = simplexml_load_string($xmlString, \Magento\Framework\View\Layout\Element::class); - $this->assertSame($this->model, $this->model->setXml($xml)); - $this->assertSame($result, $this->model->isCacheable()); + $this->structureMock->method('hasElement')->with($blockName)->willReturn($hasElement); + + $this->assertTrue($this->model->loadString($xmlString)); + $this->assertSame($cacheable, $this->model->isCacheable()); } /** * @return array */ - public function isCacheableDataProvider() + public function isCacheableDataProvider(): array { return [ - [ - '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' - . '<block></block></layout>', - true, + 'blockWithoutName' => [ + 'xml' => '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<block></block></layout>', + 'blockName' => '', + 'hasElement' => true, + 'cacheable' => true, ], - [ - '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' - . '<block cacheable="false"></block></layout>', - false + 'notCacheableBlockWithoutName' => [ + 'xml' => '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<block cacheable="false"></block></layout>', + 'blockName' => '', + 'hasElement' => true, + 'cacheable' => true, + ], + 'notCacheableBlockWithMissingBlockReference' => [ + 'xml' => '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<referenceBlock name="not_existing_block">' + . '<block name="non_cacheable_block" cacheable="false"></block>' + . '</referenceBlock></layout>', + 'blockName' => 'non_cacheable_block', + 'hasElement' => false, + 'cacheable' => true, + ], + 'notCacheableBlockWithMissingContainerReference' => [ + 'xml' => '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<referenceContainer name="not_existing_container">' + . '<block name="non_cacheable_block" cacheable="false"></block>' + . '</referenceContainer></layout>', + 'blockName' => 'non_cacheable_block', + 'hasElement' => false, + 'cacheable' => true, + ], + 'notCacheableBlockWithExistingBlockReference' => [ + 'xml' => '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<referenceBlock name="existing_block">' + . '<block name="non_cacheable_block" cacheable="false"></block>' + . '</referenceBlock></layout>', + 'blockName' => 'non_cacheable_block', + 'hasElement' => true, + 'cacheable' => false, + ], + 'notCacheableBlockWithExistingContainerReference' => [ + 'xml' => '<?xml version="1.0"?><layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + . '<referenceContainer name="existing_container">' + . '<block name="non_cacheable_block" cacheable="false"></block>' + . '</referenceContainer></layout>', + 'blockName' => 'non_cacheable_block', + 'hasElement' => true, + 'cacheable' => false, ], ]; } - public function testGenerateElementsWithoutCache() + /** + * @return void + */ + public function testGenerateElementsWithoutCache(): void { $this->readerContextFactoryMock->expects($this->once()) ->method('create') ->willReturn($this->readerContextMock); $layoutCacheId = 'layout_cache_id'; $handles = ['default', 'another']; - /** @var \Magento\Framework\View\Layout\Element $xml */ - $xml = simplexml_load_string('<layout/>', \Magento\Framework\View\Layout\Element::class); + /** @var Element $xml */ + $xml = simplexml_load_string('<layout/>', Element::class); $this->model->setXml($xml); - $themeMock = $this->getMockForAbstractClass(\Magento\Framework\View\Design\ThemeInterface::class); + $themeMock = $this->getMockForAbstractClass(ThemeInterface::class); $this->themeResolverMock->expects($this->once()) ->method('get') ->willReturn($themeMock); @@ -791,20 +923,22 @@ public function testGenerateElementsWithoutCache() 'field_3_1' => '1244', 'field_3_2' => null, 'field_3_3' => false, - ] + ], ]; - $this->pageConfigStructure->expects($this->any())->method('__toArray') + $this->pageConfigStructure->expects($this->any()) + ->method('__toArray') ->willReturn($pageConfigStructureData); $layoutScheduledStructureData = [ 'field_1' => 1283, - 'field_2' => 'text_qwertyuiop[]asdfghjkl;' + 'field_2' => 'text_qwertyuiop[]asdfghjkl;', ]; - $this->layoutScheduledSructure->expects($this->any())->method('__toArray') + $this->layoutScheduledSructure->expects($this->any()) + ->method('__toArray') ->willReturn($layoutScheduledStructureData); $data = [ 'pageConfigStructure' => $pageConfigStructureData, - 'scheduledStructure' => $layoutScheduledStructureData + 'scheduledStructure' => $layoutScheduledStructureData, ]; $this->cacheMock->expects($this->once()) @@ -812,7 +946,7 @@ public function testGenerateElementsWithoutCache() ->with(json_encode($data), 'structure_' . $layoutCacheId, $handles) ->willReturn(true); - $generatorContextMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Generator\Context::class) + $generatorContextMock = $this->getMockBuilder(Context::class) ->disableOriginalConstructor() ->getMock(); $this->generatorContextFactoryMock->expects($this->once()) @@ -827,9 +961,9 @@ public function testGenerateElementsWithoutCache() $elements = [ 'name_1' => ['type' => '', 'parent' => null], - 'name_2' => ['type' => \Magento\Framework\View\Layout\Element::TYPE_CONTAINER, 'parent' => null], + 'name_2' => ['type' => Element::TYPE_CONTAINER, 'parent' => null], 'name_3' => ['type' => '', 'parent' => 'parent'], - 'name_4' => ['type' => \Magento\Framework\View\Layout\Element::TYPE_CONTAINER, 'parent' => 'parent'], + 'name_4' => ['type' => Element::TYPE_CONTAINER, 'parent' => 'parent'], ]; $this->structureMock->expects($this->once()) @@ -839,17 +973,20 @@ public function testGenerateElementsWithoutCache() $this->model->generateElements(); } - public function testGenerateElementsWithCache() + /** + * @return void + */ + public function testGenerateElementsWithCache(): void { $layoutCacheId = 'layout_cache_id'; - /** @var \Magento\Framework\View\Layout\Element $xml */ - $xml = simplexml_load_string('<layout/>', \Magento\Framework\View\Layout\Element::class); + /** @var Element $xml */ + $xml = simplexml_load_string('<layout/>', Element::class); $this->model->setXml($xml); $this->readerContextFactoryMock->expects($this->once()) ->method('create') ->willReturn($this->readerContextMock); - $themeMock = $this->getMockForAbstractClass(\Magento\Framework\View\Design\ThemeInterface::class); + $themeMock = $this->getMockForAbstractClass(ThemeInterface::class); $this->themeResolverMock->expects($this->once()) ->method('get') ->willReturn($themeMock); @@ -871,18 +1008,20 @@ public function testGenerateElementsWithCache() 'field_3_3' => false, ] ]; - $this->pageConfigStructure->expects($this->once())->method('populateWithArray') + $this->pageConfigStructure->expects($this->once()) + ->method('populateWithArray') ->with($pageConfigStructureData); $layoutScheduledStructureData = [ 'field_1' => 1283, - 'field_2' => 'text_qwertyuiop[]asdfghjkl;' + 'field_2' => 'text_qwertyuiop[]asdfghjkl;', ]; - $this->layoutScheduledSructure->expects($this->once())->method('populateWithArray') + $this->layoutScheduledSructure->expects($this->once()) + ->method('populateWithArray') ->with($layoutScheduledStructureData); $data = [ 'pageConfigStructure' => $pageConfigStructureData, - 'scheduledStructure' => $layoutScheduledStructureData + 'scheduledStructure' => $layoutScheduledStructureData, ]; $this->cacheMock->expects($this->once()) @@ -895,7 +1034,7 @@ public function testGenerateElementsWithCache() $this->cacheMock->expects($this->never()) ->method('save'); - $generatorContextMock = $this->getMockBuilder(\Magento\Framework\View\Layout\Generator\Context::class) + $generatorContextMock = $this->getMockBuilder(Context::class) ->disableOriginalConstructor() ->getMock(); $this->generatorContextFactoryMock->expects($this->once()) @@ -910,9 +1049,9 @@ public function testGenerateElementsWithCache() $elements = [ 'name_1' => ['type' => '', 'parent' => null], - 'name_2' => ['type' => \Magento\Framework\View\Layout\Element::TYPE_CONTAINER, 'parent' => null], + 'name_2' => ['type' => Element::TYPE_CONTAINER, 'parent' => null], 'name_3' => ['type' => '', 'parent' => 'parent'], - 'name_4' => ['type' => \Magento\Framework\View\Layout\Element::TYPE_CONTAINER, 'parent' => 'parent'], + 'name_4' => ['type' => Element::TYPE_CONTAINER, 'parent' => 'parent'], ]; $this->structureMock->expects($this->once()) @@ -922,17 +1061,21 @@ public function testGenerateElementsWithCache() $this->model->generateElements(); } - public function testGetXml() + /** + * @return void + */ + public function testGetXml(): void { $xml = '<layout/>'; - $this->assertSame($xml, \Magento\Framework\View\Layout::LAYOUT_NODE); + $this->assertSame($xml, Layout::LAYOUT_NODE); } /** * @param mixed $displayValue + * @return void * @dataProvider renderElementDisplayDataProvider */ - public function testRenderElementDisplay($displayValue) + public function testRenderElementDisplay($displayValue): void { $name = 'test_container'; $child = 'child_block'; @@ -945,14 +1088,14 @@ public function testRenderElementDisplay($displayValue) [ [$name, 'display', $displayValue], [$child, 'display', $displayValue], - [$child, 'type', \Magento\Framework\View\Layout\Element::TYPE_BLOCK] + [$child, 'type', Element::TYPE_BLOCK], ] ); $this->structureMock->expects($this->atLeastOnce())->method('hasElement') ->willReturnMap( [ - [$child, true] + [$child, true], ] ); @@ -961,10 +1104,10 @@ public function testRenderElementDisplay($displayValue) ->with($name) ->willReturn($children); - $block = $this->createMock(\Magento\Framework\View\Element\AbstractBlock::class); + $block = $this->createMock(AbstractBlock::class); $block->expects($this->once())->method('toHtml')->willReturn($blockHtml); - $renderingOutput = new \Magento\Framework\DataObject(); + $renderingOutput = new DataObject(); $renderingOutput->setData('output', $blockHtml); $this->eventManagerMock->expects($this->at(0)) @@ -990,7 +1133,6 @@ public function testRenderElementDisplay($displayValue) */ public function testRenderElementDoNotDisplay($displayValue) { - $displayValue = 'false'; $name = 'test_container'; $blockHtml = ''; @@ -1004,19 +1146,19 @@ public function testRenderElementDoNotDisplay($displayValue) /** * @return array */ - public function renderElementDoNotDisplayDataProvider() + public function renderElementDoNotDisplayDataProvider(): array { return [ ['false'], ['0'], - [0] + [0], ]; } /** * @return array */ - public function renderElementDisplayDataProvider() + public function renderElementDisplayDataProvider(): array { return [ [true], @@ -1024,7 +1166,7 @@ public function renderElementDisplayDataProvider() [1], ['true'], [false], - [null] + [null], ]; } } diff --git a/lib/web/mage/adminhtml/browser.js b/lib/web/mage/adminhtml/browser.js index d6502af9ab74b..06a77cb46064b 100644 --- a/lib/web/mage/adminhtml/browser.js +++ b/lib/web/mage/adminhtml/browser.js @@ -418,7 +418,10 @@ define([ }).done($.proxy(function () { self.tree.jstree('refresh', self.activeNode.id); self.reload(); - $(window).trigger('fileDeleted.mediabrowser'); + $(window).trigger('fileDeleted.mediabrowser', { + ids: self.activeNode.id + }); + }, this)); },